CSRF защита в глубине

В настоящее время я добавляю механизм защиты токенов CSRF в свое php-приложение.
Пока я читаю, единственным требованием является уникальный токен для каждого пользователя, который я генерирую с помощью random_bytes в php7.

Меня беспокоит то, что если злоумышленник отправит http-запрос через браузер пользователя, не отправит ли браузер переменную сеанса токена? (потому что у пользователя есть идентификатор сеанса, связанный с токеном).

Я храню токен внутри скрытого значения echo’d из переменной сеанса.

Например: мой токен хранится в переменной сеанса, а затем злоумышленник отправляет меня на страницу смены пароля с защитой csrf, проверка не пройдет? (У меня уже есть правильный идентификатор сеанса в файлах cookie моих браузеров).

Спасибо

0

Решение

Вот как работает атака CSRF:

Алиса (вольно или невольно) посещает compromised.com

compromised.com делает HTTP-сообщение † запрос к yoursite.com, используя форму HTML, или JavaScript, или Flash, или что угодно, что может сделать HTTP-запрос на публикацию.

<form method=post action="http://yoursite.com/change-password">
<input name=password value=666>
<input name=confirm_password value=666>
</form>

Это работает, потому что веб-браузер отправит Алису yoursite.com сессионный файл cookie для yoursite.com,

Из-за Политика того же происхождения, compromised.com может отправить любые данные, которые он хочет на любой сайт, но не могу прочитать данные с других сайтов.

Вот как работает защита от CSRF:

yoursite.com требует переменную HTTP post request _csrf_token (или аналогичный) и сравнивает его с тем, что вы сохранили для Алисы в на стороне сервера память сеанса

Ты пишешь _csrf_tokenзначение в скрытый ввод в ваших HTML-формах, поэтому он автоматически отправляется с сообщениями формы из yoursite.com

compromised.com не могу прочитать значение _csrf_token от yoursite.com из-за политики того же происхождения, поэтому его попытки опубликовать yoursite.com не удастся.

<form method=post action="http://yoursite.com/change-password">
<input name=password value=666>
<input name=confirm_password value=666>
<input name=_csrf_token value="???">
</form>

† это не должно быть сообщение, но это распространено

1

Другие решения

Других решений пока нет …