* Таймер за активност на потребителска сесия
Публикувано на 15 ноември 2008 в раздел ОСУП.
Както вече споменахме в статията за фиксиране на потребителски сесии, е добре приложенията, които пишем, да имат собствен таймер за активност, който е независим от настройките на сървъра. За щастие това се оказва доста лесна задача, тъй като всички езици за програмиране ни дават възможност за достъп до системния часовник на сървъра. В PHP ще реализираме тази функционалност чрез функцията time(). Тя връща броя секунди изминали от началото на "UNIX епохата", т.е. от 1 януари 1970. Нека преправим вече разгредания пример така, че да прекратява сесията ако тя е била неактивна повече от пет минути:
<?php session_start(); session_regenerate_id(true); ?> <html> <head> <title>WorldBank.dom session page</title> </head> <body> <?php $timeout = 5 * 60; // 5 минути $curtime = (int)time(); if (isset($_SESSION['last_active'])){ if ($curtime-$_SESSION['last_active'] > $timeout){ echo 'Session timeout'; session_destroy(); return; } } $_SESSION['last_active'] = $curtime; echo 'session id is: '; echo session_id(); echo '<br>'; if (!isset($_SESSION['counter'])){ $_SESSION['counter'] = 0; } else{ $_SESSION['counter']++; } echo 'counter: '; echo $_SESSION['counter']; ?> </body></html>
За да проверите примера намалете стойността на $timeout на 5 (т.е. 5 секунди) и отворете страницата. Направете няколко пъти refresh и ще видите, че всичко работи нормално. Ако обаче изчакате 6 или повече секунди и дадете refresh, то ще се получи session timeout.
Чрез такъв таймер може да предположим, че на атакуващият ще му е значително по-трудно да фиксира сесия, тъй като той трябва да я поддържа активна. Ние можем да го затрудним още повече, като добавим таймер за максимален живот на сесия. Такива таймери не са подходящи за всякакъв вид услуга, но в повечето случаи намират приложение.
<?php session_start(); session_regenerate_id(true); ?> <html> <head> <title>WorldBank.dom session page</title> </head> <body> <?php $timeout = 5 * 60; $curtime = (int)time(); $maxSessionTime = 5 * 60 * 60; // 5 часа if(! isset($_SESSION['initial_time'])){ $_SESSION['initial_time'] = (int)time(); } if($curtime-$_SESSION['initial_time'] > $maxSessionTime){ echo 'Maximum session time exceeded'; session_destroy(); return; } if (isset($_SESSION['last_active'])){ if ($curtime-$_SESSION['last_active'] > $timeout){ echo 'Session timeout'; session_destroy(); return; } } $_SESSION['last_active'] = $curtime; echo 'session id is: '; echo session_id(); echo '<br>'; if (!isset($_SESSION['counter'])){ $_SESSION['counter'] = 0; } else{ $_SESSION['counter']++; } echo 'counter: '; echo $_SESSION['counter']; ?> </body></html>
Отново тествайте програмата, като намалите таймерите. Ще видите, че сесията ще приключи независимо, че се опитвате да я поддържате активна.
Задача: Възможно е атакуващият да "провали" нашите таймери чрез още друг вид атака - ако например успее да върне часовника на сървъра назад. В такъв случай сравненията от по-горните примери няма да функционират правилно. Помислете как може да защитим приложението срещу такъв exploit.
Добави коментар