Защита CSRF путем сохранения одноразового номера в переменной и форме сеанса - PullRequest
10 голосов
/ 12 февраля 2010

Для защиты от CSRF вы должны поместить одноразовый номер в скрытое поле в форме, в файл cookie или в переменную сеанса. Но что, если пользователь открывает несколько страниц в разных вкладках? В этом случае каждая вкладка будет иметь форму с уникальным одноразовым номером, но в переменной сеанса или cookie будет храниться только один одноразовый номер. Или, если вы попытаетесь сохранить все одноразовые номера в переменной cookie / session, как вы определите, какой из них принадлежит какой форме?

Ответы [ 4 ]

6 голосов
/ 12 февраля 2010

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

Вы захотите, чтобы злоумышленникам было трудно перехватывать идентификаторы сеансов и создавать свои собственные одноразовые номера. Таким образом, один из способов сделать это - использовать HMAC-SHA256 (или подобное) для хеширования идентификатора сеанса, используя ключ, который вы не предоставляете общественности.

(Очевидно, что если злоумышленник может получить фактический идентификатор сеанса сам, он может уже перехватить сеанс. Так что это не то, о чем я говорю, а скорее способность злоумышленника создать сценарий (который выполняется на жертве). компьютер), который может каким-то образом захватить идентификатор сеанса и использовать его для динамической генерации URL с предварительно заполненным одноразовым номером.)


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

Один из подходов заключается в создании нового одноразового номера для каждой формы, который содержит метку времени, а также hash(timestamp . sessionid) (где hash - это некоторый вариант HMAC, как описано выше, для предотвращения подделки, а . - строка конкатенация). Затем вы проверяете одноразовый номер:

  1. проверка метки времени, чтобы убедиться, что одноразовый номер достаточно свежий (это зависит от вашей политики, но обычно несколько часов)
  2. затем, вычисляя хеш на основе метки времени и идентификатора сеанса, и сравнивая с одноразовым номером, чтобы убедиться в подлинности одноразового номера

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

3 голосов
/ 24 октября 2013

То, что вы описываете, больше не является одноразовым номером (nonce = число, используемое один раз ), это просто идентификатор сеанса. Смысл одноразового номера в том, что он действителен только для одной отправки формы, поэтому обеспечивает большую защиту от перехвата, чем просто идентификатор сеанса, но за счет невозможности одновременной работы нескольких вкладок на сайте.

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

2 голосов
/ 12 февраля 2010

Некоторые люди генерируют токен для каждой формы, и это очень безопасный подход. Однако это может сломать ваше приложение и разозлить пользователей. Чтобы предотвратить использование XSRF для вашего сайта, вам просто необходима уникальная переменная 1 токена на сеанс, и тогда злоумышленник не сможет подделать какой-либо запрос, если он не сможет найти этот 1 токен. Незначительная проблема этого подхода заключается в том, что злоумышленник может перебить этот токен, пока жертва посещает веб-сайт, который контролирует злоумышленник. ОДНАКО, если токен довольно большой, например, 32 байта или около того, то для полного перебора потребуется много лет, и сеанс http должен истечь задолго до этого.

0 голосов
/ 11 сентября 2013

Давным-давно этот пост был написан. Я реализовал блокатор csrf, который, я уверен, хорошо защищает. Он работает с несколькими открытыми окнами, но я все еще оцениваю, какую защиту он предлагает. Он использует подход БД, т.е. хранит вместо сессии таблицу. ПРИМЕЧАНИЕ: в этом случае я использую MD5 в качестве простого механизма защиты от SQL

Псевдокод:

ФОРМА:

token = randomstring #to be used in form hidden input
db->insert into csrf (token, user_id) values (md5(token),md5(cookie(user_id))

- токен хранится в БД до получения доступа из сценария действия, приведенного ниже:

СКРИПТ ДЕЙСТВИЯ:

if md5(post(token)) belongs to md5(cookie(user_id)) 
    #discard the token
    db -> delete from csrf where token=md5(post(token)) and user_id=md5(cookie(user_id)) 
    do the rest of the stuff
...