* Таймер за активност на потребителска сесия
Публикувано на 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.
Добави коментар