Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Уязвимое место сессий или несколько слов о синхронизации (https://forum.antichat.xyz/showthread.php?t=82754)

desTiny 28.08.2008 17:08

Уязвимое место сессий или несколько слов о синхронизации
 
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


Время: 21:11