Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Уязвимое место сессий или несколько слов о синхронизации |

28.08.2008, 17:08
|
|
Reservists Of Antichat - Level 6
Регистрация: 04.02.2007
Сообщений: 1,152
Провел на форуме: 3008839
Репутация:
1502
|
|
Уязвимое место сессий или несколько слов о синхронизации
INTRO
Сейчас я опишу грабли, на которые чуть сам не наступил. А они могли бы привести к серьёзным последствиям...
BODY
(показываю на примере PHP)
Пусть у нас есть код, в котором используются сессии. Пусть в сессиях хранится, скажем, уровень доступа пользователя - число, которое может увеличиться, если пользователь что-то сделает. Этот же уровень доступа хранится в БД. Пусть пользователю для увеличения уровня доступа надо ответить на вопрос.
Можно написать такой код, выполняющий соответствующее действие:
1-ый косяк:
PHP код:
// при логине аналогично level берётся из БД.
session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$answer = //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
print "ok";
$_SESSION['level']++;
//коннект к БД
mysql_query("Update `auth` set level=level+1 where id=".$_SESSION['id']);
//отключение от БД
}
2-ой косяк:
PHP код:
// при логине аналогично level берётся из БД.
session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$answer = //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
print "ok";
$level = ++$_SESSION['level'];
if ($level === $maximum_level){
//выполняем секретный код для очень крутых пацанов
}
}
//лирическое отступление, положенное в таких случаях
Казалось бы - всё правильно, но... это не так.
//лирическое отступление закончилось
//Пояснение к первому косяку
Что можно сделать в таком случае? Пусть мошенник (пользуясь именами от Брюса Шнаера) Ева знает ответ на первый вопрос. Сейчас я покажу, что ей этого достаточно, чтобы попасть на любой уровень. Для этого она открывает несколько сессий с первым уровнем (в банальном случае - несколькими броузерами), и в каждой сессии отвечает на вопрос. При каждом ответе инкрементируется как уровень в сессии, так и уровень в БД. Сессии друг от друга не зависят, зато БД - общая! Тем самым мы неограниченное количество раз переходим на следующий уровень.
////Фикс 1
Фикс не очень хороший, ибо при случайном использовании двух сессий (открыл человек двумя броузерами, потом запутался, заново ответил на уже пройденный вопрос) может привести к нежелательному откату назад.
PHP код:
// при логине аналогично level берётся из БД.
session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$answer = //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
session_start();
print "ok";
$level=++$_SESSION['level'];
//коннект к БД
mysql_query("Update `auth` set `level`='$level' where id=".$_SESSION['id']);
//отключение от БД
}
////Конец фикса 1
////Фикс 2
PHP код:
// при логине аналогично level берётся из БД.
session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$bdlev = //из бд получаем уровнь пользователя $_SESSION['id'];
($bdlev===$_SESSION['level']) or die("Relogin please!");
$answer = //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
session_start();
print "ok";
$level = ++$_SESSION['level'];
//коннект к БД
mysql_query("Update `auth` set `level`='$level' where id=".$_SESSION['id']);
//отключение от БД
}
////Конец фикса 2
//Пояснение к первому косяку кончилось
//Пояснение ко второму косяку
Тут аналогичная ошибка, только более общий случай. Мы можем таким образом многократно вызвать один и тот же код, который мог планироваьтся единожды - к примеру, запись в таблицу результатов.
////Фикс
Фикс аналогичен Фиксу 2 из 1-го косяка - надо СИНХРОНИЗИРОВАТЬ данные в БД и сессии.
////Фикс кончился
//Пояснение ко второму косяку кончилось
OUTRO
Эх, сколько же ошибок может спровоцировать неправильная синхронизация и распараллеливание! Притом ошибок - трудноисправимых.
GREETZ
Они сами знают, кому
(с) desTiny, 2008
__________________
Bedankt euch dafür bei euch selbst.
H_2(S^3/((z1, z2)~(exp(2pi*i/p)z1, exp(2pi*q*i/p)z2)))=Z/pZ
Последний раз редактировалось desTiny; 11.09.2008 в 23:19..
|
|
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|