Как происходит такая атака рассказанно в Ruby on Rails Security Guide, возьму от туда лишь картинку иллюстрирующую процесс атаки:

Предотвратить такую атаку в классическом (не ajax) приложении можно только одним мало приятным способом – дописывать к каждый ссылке и к каждой форме параметры с токеном. В случае ajax приложения мы можем сделать защиту более удобной – без лишних токенов в ссылках.
Как это устроено?
Мы добавляем к каждому запросу заголовок X-CSRF-Token и проверяем этот токен классическим путем.
Передаем токен от сервера клиенту в виде куки, а при ajax запросе просто добавляем его к заголовкам. Кука действительна только в рамках домена, поэтому у нас её не утащат (надеемся что других уязвимостей в нашем web-сервисе нет)
У нас есть 3 случая которые нужно проверять на стороне сервера:
- Ajax запрос с верным токеном – всё ок, показываем страницу, выдаем новый токен
- Ajax запрос с неверным токеном – шлем лесом (скорее всего левый ajax запрос с другого сайта)
- НЕ-Ajax запрос
Последний случай требует специальной обработки, т.к. это именно img src=»..» или iframe src=»…», но так же это может быть первый вход в приложение или F5 или открытие ссылки в новой вкладке.
В случае если к нам пришел такой запрос я выполняю следующий код:
if (preg_match('/\?/i',$_SERVER['REQUEST_URI'])){
$token = "&csrf_token=".$token;
}else{
$token = "?csrf_token=".$token;
}
$url = $_SERVER['REQUEST_URI'].$token;
echo "
-html
-body
Loading....
-script type='text/javascript'
if (parent.document.location.href == document.location.href){
document.location.href='".$url."';
}
-/script
-/body
-/htm;
";
die;
Что он делает (сорри форматер в блоге сломался)? Он выполняет js. о! в теге img js не выполнитсья!
На случай iframe мы проверяем parent.document.location.href == document.location.href – если это iframe – то редирект не произойдет.
Нам осталось только дописать что если токена нет в заголовках, будем ждать его в $_GET.
Таким образом мы защитились от CSRF лучше других: мы не только не даём делать действия, но и не даем узнать информаию пользователя (обрубается любой запрос без токера), мы защищаемся не только от дургих доменов, но и от своего
если у нас найдут XSS и воткнут туда img src=’..’ или iframe src=»..» оно злоумышленику не поможет.
Всем удачи!