Я хочу знать, достаточно ли этот код для предотвращения атаки CSRF на PHP-форму?
<?php session_start(); session_regenerate_id(true); if (isset($_POST['submit'])) { if (isset($_SESSION['token']) && ($_POST['token'] == $_SESSION['token'])) { } } $token = hash('sha256', uniqid(mt_rand(), true)); $_SESSION['token'] = $token; ?> //FORM <form method="POST" action="page.php"> <input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="submit" name="submit"> </form>
Благодарю.
Если жертва не просмотрела какие-либо формы на вашем сайте, он еще не будет иметь токен, хранящийся на его сеансе.
Если злоумышленник представляет жертву форму без поля токена вообще, запрос POST, сделанный жертвой, пройдет проверку CSRF, потому что $_POST['token']
и $_SESSION['token']
будут равны нулю. (Или обе пустые строки в зависимости от того, как PHP инициализирует неизвестные переменные.)
Вы также должны проверить, существует ли токен в сеансе перед проверкой равенства и прерывания, если один из этих тестов завершился с ошибкой.
В зависимости от вашего сайта пользователь, не увидев форму, может быть очень вероятным или может быть крайним случаем. При проверке наличия маркера во-первых, не имеет значения, сколько форм у вас на вашем сайте, нет возможности атаки CSRF.
Помимо этой небольшой проблемы, я не вижу в ней уязвимости CSRF. Этот код выглядит так, как будто он выполнит эту работу.
Я бы сказал, что этого достаточно для данной цели.
Значения, возвращаемые uniqid(mt_rand(), true)
должны быть до 33 байтов:
mt_rand
php_combined_lcg
Однако эти 33 байта не содержат 264 бита энтропии, а наоборот:
mt_rand
Это составляет почти 81 неизвестный бит. Для грубой силы это потребует в среднем 2 81/2 ≈ 1,2 · 10 24 догадки, которые приводят к заданному токену при хэшировании. Данные для обработки будут составлять приблизительно 8 · 10 13 ТБ. С сегодняшним компьютером вы сможете запустить это примерно за 5,155 · 10 17 секунд.
Этого должно быть достаточно, чтобы сделать атаку неосуществимой.
На продуктах, которые я поддерживаю, я бы сказал «нет». Генератор случайных чисел основан на rand (), который предсказуем. Кроме того, похоже, что случайное число очень короткое – оно должно быть достаточно длинным, чтобы оно не могло быть грубо принудительным во время действия сессии – ни кавычки ни одного из многих токенов CSRF активных сессий.
Проверьте страницу OWASP на CSRF. Они дадут вам хорошее руководство.