Уязвимость CSRF. Введение

24 комментария

Да я помню что я обещал в предыдущем сообщении написать про капчу, но, честно говоря, писать про эти капчи у меня уже сил нет. Да и надоело то, что мне, как аналитику ИБ, приходят в личку только предложения по взлому капч, и никакой другой нормальной работы.

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

Этот цикл статей будет посвящен CSRF уязвимостям. Не слышали такой термин? Значит этот цикл для вас ;)

Введение

Конечно, нынче уже каждый более менее опытный разработчик наслышан про такие классические уязвимости как:

  • SQL injection
  • PHP include
  • XSS

Раньше, на заре развития интернета, практически каждое приложение содержало кучу таких уязвимостей. Но с каждым днем становилось все сложней встретить уязвимости такого типа. И взломщики становились все более изощреннее, что приводило к разработкам новых типов и векторов атаки — один из этих типов атаки был выделен в отдельный класс и получил название CSRF.

Что такое CSRF. Теория

Зайдем на википедию:

CSRF (англ. Сross Site Request Forgery — «Подделка межсайтовых запросов», также известен как XSRF) — вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP. Если жертва заходит на сайт, созданный злоумышленником, от её лица тайно отправляется запрос на другой сервер (например, на сервер платёжной системы), осуществляющий некую вредоносную операцию (например, перевод денег на счёт злоумышленника). Для осуществления данной атаки, жертва должна быть авторизована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, который не может быть проигнорирован или подделан атакующим скриптом.

Если более понятным языком, то это атака, при которой злоумышленник пытается вынудить браузер жертвы создать запрос к целевому серверу, втайне от самой жертвы. Схематично это будет выглядеть следующим образом:

Данная атака в чем то похоже на классическую XSS, в которой злоумышленнику необходимо было вынудить жертву перейти по некоторой ссылке на уязвимую страницу. Здесь же необходимо вынудить пользователя перейти на специально подготовленную злоумышленником страницу, на которую был добавлен некоторый код. При выполнении данного кода браузер жертвы совершает некий запрос к другому серверу (допустим под видом загрузки изображения), и тем самым выполняет некие, нужные злоумышленнику, действия.

Опасность CSRF в том, что данное поведение браузеров и всего HTTP протокола является нормальным. К примеру, ведь нормально то, что сайт может на своих страницах содержать картинки с другого сайта. А браузеру неизвестно заранее что именно пытаются заставить его загрузить, действительно картинку, или под видом данной загрузки будет выполнено какое то действие на целевом сайте.

Немножко практики

Возьмем, к примеру, целевой сферический сайт в вакууме, который имеет вполне стандартную админку с функцией добавления нового администратора:
Уязвимая к CSRF форма
Разработчик данной формы ничего не знал об уязвимости CSRF, и защиты от нее он, естественно, не делал. Ну и плюс ко всему (чтобы пример был проще) он передавал данные методом GET. По нажатию кнопки «создать» браузер сформирует запрос к следующей странице:
http://site/admin/?do=add_admin&new_login=NewAdmin&new_pass=NewPass&new_mail=NewAdmin@Mail.Com
И после того как запрос будет выполнен, на данном сайте появится новый администратор. Казалось бы что с того — это вполне обычная функциональность на многих сайтах. Но здесь то и кроется главная ошибка. Жертву можно заставить выполнить данный запрос при заходе на абсолютно другой сайт. Создаем следующую страницу по адресу http://evil/page.html
<html>
<head>
<title>Обычная страница</title>
</head>
<body>
С обычным текстом. Но с необычным содержимым
<img src="http://site/admin/?do=add_admin&new_login=Xaker&new_pass=Pass&new_mail=xaker@evil.Com" alt="" width="1" height="1" />
</body>
</html>

И теперь, если жертва зайдет на http://evil/page.html, то браузер попытается загрузить картинку, но вместо этого выполнит запрос к админ панели, тем самым создав нового администратора. Единственным обязательным условием успешной эксплуатации данной уязвимости является необходимость того, что жертва должна быть авторизована на уязвимом сервере в момент проведения атаки.

Заключение

С тем, что такое CSRF мы разобрались. Давайте попробуем выделить основные требования для успешного проведения атаки:

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

И на основе этих требований попытаемся построить защиту в следующей статье…

Читайте также:

  1. Уязвимость CSRF. Введение
  2. Уязвимость CSRF. Защита
  3. Уязвимость CSRF. Скрываем Referer при редиректе

PS: продолжение следует ;)

      1. Из-за 101 км

        обещал статью про капчу, а тут статья про csrf

        Какая разница, то же и к капчам относится…

        «Здесь же необходимо вынудить пользователя перейти на специально подготовленную злоумышленником страницу».

        Можно же не посетителей «вынуждать», а вебмастеров привлекать красивыми бесплатными плагинами к капча- или другим сторонним сервисам, которые все будут устанавливать себе на сайты.
        Да ещё и доугим советовать.

        И вуаля — грузи ничего не подозревающим посетителям, при активной попомощи ничего не подозревающих и не контролирующих вебмастеров-пофигистов, умиляющизся отсутствию спама на их сайтах, всё, что угодно откуда угодно в браузеры посетителей.

  1. Костя

    Вы очень понятно описали суть понятия CSRF, но картинка со схемой атаки неправильно показывает, что сервер злоумышленника отправляет запрос на целевой сайт.
    Вы же чётко написали «браузер пользователя отправляет запрос на другой сайт, где пользователь должен быть залогинен в этот момент».

    1. Дмитрий Амиров Автор

      Все же в некотором смысле сервер злоумышленника заставляет браузер пользователя выполнить запрос на другой сайт.
      Присмотритесь, может не совсем понятно я нарисовал, но на картинке изображена страница с неким кодом, расположенная на сервере злоумышленника, который и инициирует обращение к третьему серверу. Почитайте сноски на самой картинке)

      1. Костя

        Нет, по поводу «некого кода» всё ясно. Именно он будет инициатором запроса на целевой сайт, но сервер злоумышленника абсолютно никак не взаимодействует из целевым сервером. Все происходит через посредника — браузер залогиненого юзера.

        1. Дмитрий Амиров Автор

          М… Никто и не говорил что сервер злоумышленника взаимодействует с целевым сервером. И на картинке опять же основной акцент делается на некий код, который является инициатором запроса на целевой сайт, а не на сервер злоумышленника.

    1. Дмитрий Амиров Автор

      Вы наверное хотели сказать — защититься от CSRF? А то как то двусмысленно получилось)
      Ну а вообще да, побольше бы статей на тему защиты. Глядишь и дырявых приложений будет меньше.

  2. sk9

    «для осуществления данной атаки, жертва должна быть авторизована на том сервере, на который отправляется запрос». То бишь для защиты себя от CSRF достаточно включённой в браузере настройки не принимать куки со сторонних сайтов, т.к. эта настройка блокирует не только приём, но и передачу кук сторонним сайтам, тем самым я всегда буду неавторизованым на каком-либо сайте, пока специально на него не зайду? Или это можно при помощи фреймов или чего-то ещё хитро обойти.

    1. Дмитрий Амиров Автор

      Я не пробовал включать эту настройку в браузере. Но, боюсь, что она не поможет. Да, атаку скорее всего провести не удастся на те сайты которые требуют куки. Уязвимым вы становитесь после того как авторизовались на сайте который подвержен CSRF, и настройки приема кукисов никак не помогут. Хз вобщем как конкретно сформулировать вам ответ. Вобщем мой совет, попробуйте вникнуть в эту атаку подробнее, тогда ответ вам станет понятен сам собой.

      1. sk9

        Прошу прощения за дотошность, но я всё равно не понял. «Уязвимым вы становитесь после того как авторизовались на сайте который подвержен CSRF» — каким образом? Ведь когда я захожу на сервер злоумышленника, то при запросе на целевой (уязвимый) сервер я ему НЕ передаю куки. Или авторизация как-то возможна без кук? Или Вы под словом «уязвимый» понимаете, что на целевом сайте каким-то образом вредоносный код завёлся, а не его хозяин из-за халатности забил на токены и рефереры не проверяет?

        1. Дмитрий Амиров Автор

          Да, вы не передаете ему свои куки, верно. Но он может заставить выполнить запрос на уязвимый сервер от вашего имени. Этот запрос браузер выполнит с вашими же куками на этом сервере. С точки зрения уязвимого сервера этот запрос ничем не отличается от остальных запросов, и успешного его выполнит. А таким запросом может быть смена пароля, добавление нового админа, смена платежных данных и прочее.

  3. Аноним

    Интересная уязвимость, спасибо. Блин, быть хакером это круто) Вот я бы никогда не догадался что такая атака имеет место быть) а кто то ведь додумался, а это очень неочевидно когда об этом не знаешь

    1. Дмитрий Амиров Автор

      Все верно, хакер — это в первую очередь человек с нестандартным мышлением, а не взломщик)

  4. Сергей

    Спасибо за интересную сатью.
    Мне не совсем ясно, а поддвержены ли этой атаке POST запрос, если да то как примерно? С GET запросом пример ясен.

    1. Дмитрий Амиров Автор

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

  5. Владислав

    Спасибо за годную статью. Вот только сейчас столкнулся с необходимостью обработки такой уязвимости.
    Вы очень подробно и правильно описали! Респект за такой пост.

Добавить комментарий

Прочли запись? Понравилась? Не стесняйтесь, оставьте, пожалуйста, свой комментарий. Мне очень интересно, что вы думаете об этом. Кстати в комментарии вы можете задать мне любой вопрос. Я обязательно отвечу.

Вы можете оставить коментарий анонимно, для этого можно не указывать Имя и email. Все комментарии проходят модерацию, поэтому ваш комментарий появится не сразу.