Как предотвратить повторное воспроизведение формы /man -in-the-middle в PHP, csrf, xsrf

У меня есть веб-форма, и я использую PHP. Я знаю, что формы можно манипулировать (я считаю, что это называется повторной атакой или атакой "человек-в-середине" ). Поэтому я хотел бы использовать токен аутентичности как скрытое поле.

Возможности угрозы, о которых я знаю, следующие:

  • Атакующий захватывает законную форму пользователя (это я считаю атакой "человек в середине" ).
  • легитимный пользователь сам является злоумышленником: он получает форму, читает токен, но использует его для отправки опасных данных (это, я считаю, является повторной атакой)

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

Теперь на вопросы:

  • Какова наилучшая практика для создания этого токена, чтобы форма без него была отклонена (например, соление?).
  • Что делают люди, чтобы убедиться, что токен не воспроизводится.

Новые небольшие вопросы, основанные на комментариях:

  • Является ли захват сеанса тем же, что и атака "человек-в-середине"?

Ответ 1

Вы упомянули CSRF в названии, но на самом деле не затронули его в своем вопросе.

Вы можете прочитать об этом подробнее онлайн, но CSRF - это в основном атака, позволяющая законному пользователю безошибочно отправлять на сайт. Например, если SO не защищает от таких атак, я мог бы создать форму, которая заставляет вашу информацию профиля SO быть измененной, когда вы нажмете на эту плохую форму, ожидая чего-то другого ( "Выиграйте миллион долларов!" Кликните сюда!!"). Эта форма будет использовать ваши cookie файлы cookie для авторизации с помощью SO и заставить его выглядеть так, чтобы вы были законным образом отправили обновления в свой профиль.

Чтобы защитить вас от этого, вы действительно хотите сделать пару вещей:

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

Альтернативой этому второму пункту является проверка того, что реферер всегда является вашим сайтом или сайтом, на котором вы ожидаете POST. Я не рекомендую это для сайтов, отличных от HTTPS, потому что некоторые браузеры/сетевые устройства вытесняют рефереры и не всегда надежны, чтобы существовал реферер.

Ответ 2

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

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

Когда пользователь успешно отправит форму с токеном, удалите токен из сеанса, поэтому всякое воспроизведение этой заявки завершится неудачно. Тем не менее, все, что требуется, - это снова запросить форму для создания еще одного токена. Затем этот новый токен можно использовать в последующих автоматических атаках. Другими словами, ноты формы полезны против CSRF, но не очень эффективны против автоматических повторов и атак типа "человек-в-середине".

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

Кроме того, если быть откровенным, к тому времени, когда вам нужно беспокоиться о повторах запросов и атаках типа "человек в середине", ваше пользовательское соединение уже скомпрометировано, и, вероятно, вы не можете сделать это, чтобы уменьшить любой ущерб. Только SSL является достаточным уровнем защиты от MITM и повторением, и если вы беспокоитесь об этом, вы будете работать под SSL...

Ответ 3

Чтобы сгенерировать этот токен, здесь стратегия, которую я использую, кажется, работает хорошо.

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

Ответ 4

csrf-magic - отличный класс для токенов CSRF, он автоматически помещает их в вашу страницу

http://csrf.htmlpurifier.org/

"csrf-magic использует возможности буферизации вывода PHP для динамической перезаписи форм и скриптов в вашем документе, а также перехватывает POST-запросы и проверяет их токен (используются различные алгоритмы, некоторые генерируют nonces, а некоторые генерируют токены, специфичные для пользователя). Это означает, что для традиционного веб-сайта с формами вы можете отказаться от csrf-magic в своем приложении и забыть об этом!"