Токены CSRF против путаницы Nonce - они одинаковые?
В попытке сделать текущее приложение, которое я разрабатываю, более безопасным, я читал о токенах CSRF, а также о Nonce - думаю, я понял идею, лежащую в основе токенов CSRF, но у меня возникают проблемы с поиском "Good & Simplified" ресурсы и примеры Nonces.
Мой вопрос просто так: токены CSRF и Nonce - это одно и то же? из того, что я мог сделать вывод, что оба эти метода имеют разные методы для достижения одной и той же цели, или я что-то неправильно понимаю?
Если они отличаются, не могли бы вы предоставить хороший пример кода или указать мне ссылки, где я могу узнать больше о том, как реализовать одноразовые номера в приложениях PHP.
Спасибо!
3 ответа
Одноразовый номер - это, как правило, некоторая случайная строка, которая добавляется в запрос только для непредсказуемого изменения данных, которые используются для вычисления подписи. Поэтому nonce обычно не используется какой-либо бизнес-логикой на стороне сервера.
Хотя CSRF-токен хранится где-то на сервере, он передается клиенту и должен быть возвращен на сервер для сравнения. А если совпадет - тогда ОК.
Так что в вашем случае лучше будет один раз сохранить токен csrf в переменной сеанса, например
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
и использовать его без изменений в течение жизни сеанса во всех формах, которые есть в вашем приложении.
(Если у вас нет random_bytes()
, используйте random_compat, чтобы заполнить его.)
Нет, они не одинаковы.
Одноразовые номера предотвращают атаки воспроизведения (не позволяют подслушивающему сохранять подписанный запрос и повторно отправлять его позже, например, если Алиса отправит "Оплатить Боба $100", вам не нужно, чтобы кто-то повторно отправлял это 100 раз).
Токены CSRF исправляют специфическую для HTML слабость в аутентификации действий пользователей, когда сторонний веб-сайт может отправлять формы с учетными данными пользователя, просматривающего сайт (например, JavaScript на evil.example.com, отправляющий форму на facebook.com с помощью вашего браузера, аутентифицируемый как вы).
Жетоны CSRF должны быть секретными, иначе у злоумышленника будет отсутствующий фрагмент, необходимый для подделки запроса.
Одноразовые номера не должны быть секретными, если они подписаны секретом запрашивающей стороны (если злоумышленник не может заменить один одноразовый номер другим).
Вы можете разрешить воспроизведение запросов с токенами CSRF и при этом быть защищенными от CSRF (вас интересует, было ли это намеренным действием со стороны пользователя, но может не обязательно помешать пользователю выполнить его много раз).
На самом деле это очень часто полезное свойство, например, позволяет пользователям использовать кнопку "Назад" и повторно отправлять формы с исправленными значениями. Если вы внедрите защиту CSRF с помощью механизма Nonce-like, вы получите ложные тревоги, когда пользователи обновят отправленные страницы.
Простой способ предотвратить CSRF без одноразовых номеров - это поместить идентификатор сеанса в скрытое поле from (не значение, сохраненное в сеансе, но идентификатор самого сеанса, то же самое, что вы храните в cookie [session_id()
в PHP]). Когда форма отправлена, проверьте, что идентификатор сеанса формы совпадает с идентификатором в файле cookie. Этого достаточно для CSRF, так как злоумышленник не может знать значение куки (CSRF позволяет злоумышленникам только слепо отправлять куки).
Это одно и то же. "Одноразовый номер" - это просто одноразовый пароль. Он может служить криптографической солью, но в основном это просто случайное значение. Смотрите WP:Nonce
Но, чтобы подвести итог, одноразовый номер часто используется в качестве токена CSRF. Это деталь реализации. Разница с другими вариантами использования заключается в том, что позже утверждается.
CSRF имеет некоторые ограничения. в случае, если у вас есть требование, где вы хотите открыть любую страницу или ссылку на новой вкладке, CSRF не позволит. существующий токен позволит открыть страницу в новой вкладке всего 5 раз. когда вы попытаетесь открыть его в шестой раз, он создаст новый токен, который не будет соответствовать "серверной стороне = токену клиентской стороны". более ранний токен истечет и будет создан новый токен (NONCE), в этом случае вы получите ошибку 404 или 405.