Перекрестная подделка запроса сайта (CSRF), обычно предотвращают с одним из следующих методов:
Моя идея состоит в том, чтобы использовать пользовательский секрет, загадочный, но статический идентификатор формы и JavaScript для генерации маркеров.
GET /usersecret/john_doe
выбранный JavaScript от аутентифицируемого пользователя.OK 89070135420357234586534346
Этот секрет концептуально статичен, но может быть изменен каждый день/час... для улучшения безопасности. Это - единственная конфиденциальная вещь.generateToken(7099879082361234103, 89070135420357234586534346)
Что-то не так с этим подходом, несмотря на то, что он не работает без JavaScript?
Приложение:
Статический идентификатор формы не обеспечивает никакой защиты; злоумышленник может получить его сам. Помните, что злоумышленник не ограничен использованием JavaScript на клиенте; он может получить статический идентификатор формы на стороне сервера.
Я не уверен, что полностью понимаю предлагаемую защиту; откуда берется GET / usersecret / john_doe
? Это часть страницы JavaScript? Это буквальный предлагаемый URL? Если это так, я предполагаю, что имя пользователя
не является секретом, а это означает, что evil.ru может восстановить секреты пользователя, если ошибка браузера или плагина разрешает междоменные запросы GET. Почему бы не сохранить секрет пользователя в файле cookie после аутентификации, а не позволить любому, кто может выполнять междоменные GET-запросы, извлекать его?
Я бы очень внимательно прочитал «Надежная защита от межсайтовой подделки» , прежде чем я реализовал мою собственную систему аутентификации, которую я хотел защитить от CSRF. Фактически, я бы вообще пересмотрел возможность внедрения собственной системы аутентификации.
Вам определенно нужно какое-то состояние на сервере для аутентификации / авторизации. Однако это не обязательно должен быть сеанс http, вы можете сохранить его в распределенном кеше (например, memcached) или в базе данных.
Если вы используете файлы cookie для аутентификации, самым простым решением является двойная отправка значения cookie. Перед отправкой формы прочтите идентификатор сеанса из файла cookie, сохраните его в скрытом поле и затем отправьте. На стороне сервера убедитесь, что значение в запросе совпадает с идентификатором сеанса (полученным из файла cookie). Злой сценарий из другого домена не сможет прочитать идентификатор сеанса из файла cookie, что предотвратит CSRF.
Эта схема использует один идентификатор в сеансе.
Если вам нужна дополнительная защита, создайте уникальный идентификатор для каждой сессии для каждой формы.
Кроме того, НЕ генерируйте токены в JS. Кто угодно может скопировать код и запустить его из другого домена для атаки на ваш сайт.