Підробку міжсайтових запитів (CSRF), як правило, запобігають одним із таких методів:
- Реферер чека - НАДІЙНИЙ, але ненадійний
- вставити маркер у форму та зберегти маркер у сеансі сервера - насправді RESTful
- загадкові одноразові URI - не RESTful з тієї ж причини, що і маркери
- надсилати пароль вручну для цього запиту (не кешований пароль, який використовується з HTTP-аутентифікацією) - RESTful, але не зручний
Моя ідея полягає у використанні секрету користувача, загадкового, але статичного ідентифікатора форми та JavaScript для генерації токенів.
<form method="POST" action="/someresource" id="7099879082361234103">
<input type="hidden" name="token" value="generateToken(...)">
...
</form>
GET /usersecret/john_doe
отриманий JavaScript від автентифікованого користувача.- Відповідь:
OK 89070135420357234586534346
Цей секрет є концептуально статичним, але його можна змінювати щодня / годину ... для підвищення безпеки. Це єдина конфіденційна річ. - Прочитайте загадковий (але статичний для всіх користувачів!) Ідентифікатор форми за допомогою JavaScript, обробіть його разом із секретом користувача:
generateToken(7099879082361234103, 89070135420357234586534346)
- Надішліть форму разом із згенерованим маркером на сервер.
- Оскільки сервер знає секрет користувача та ідентифікатор форми, можна запустити ту саму функцію createToken, що і клієнт перед надсиланням, і порівняти обидва результати. Тільки коли обидва значення рівні, дія буде дозволена.
Щось не так із цим підходом, незважаючи на те, що він не працює без JavaScript?
Додаток: