Безопасен ли доступ к токену CSRF-защиты сеанса? - PullRequest
16 голосов
/ 28 сентября 2008

Django поставляется с Промежуточным программным обеспечением защиты CSRF , которое генерирует уникальный токен для каждого сеанса для использования в формах. Он сканирует все входящие POST запросы на правильный токен и отклоняет запрос, если токен отсутствует или недействителен.

Я хотел бы использовать AJAX для некоторых запросов POST, но указанные запросы не имеют маркера CSRF. На страницах нет элементов <form>, и я бы не стал путать разметку, вставляя токен как скрытое значение. Я полагаю, что хороший способ сделать это состоит в том, чтобы выставить vew, такой как /get-csrf-token/, для возврата токена пользователя, полагаясь на правила межсайтового скриптинга браузера, чтобы не запрашивать его у враждебных сайтов.

Это хорошая идея? Существуют ли более эффективные способы защиты от CSRF-атак с одновременным разрешением запросов AJAX?

Ответы [ 3 ]

16 голосов
/ 10 февраля 2009

ОБНОВЛЕНИЕ : ниже верно и должно быть верно, если все браузеры и плагины были правильно реализованы. К сожалению, теперь мы знаем, что это не так, и что определенные комбинации плагинов и перенаправлений браузера могут позволить злоумышленнику предоставить произвольные заголовки при междоменном запросе. К сожалению, это означает, что даже запросы AJAX с заголовком «X-Requested-With: XMLHttpRequest» теперь должны быть защищены CSRF. В результате Django больше не освобождает запросы Ajax от защиты CSRF .

Оригинальный ответ

Стоит отметить, что защита запросов AJAX от CSRF не нужна, поскольку браузеры не допускают межсайтовые запросы AJAX. Фактически, промежуточное программное обеспечение Django CSRF теперь автоматически исключает запросы AJAX из сканирования токенов CSRF .

Это допустимо только в том случае, если вы на самом деле проверяете сторону сервера заголовка X-Requested-With для значения «XMLHttpRequest» (что делает Django) и только исключаете реальные запросы AJAX из сканирования CSRF.

12 голосов
/ 28 сентября 2008

Если вы знаете, что вам понадобится токен CSRF для запросов AJAX, вы всегда можете вставить его в HTML где-нибудь; затем вы можете найти его через Javascript, пройдя через DOM. Таким образом, вы по-прежнему будете иметь доступ к токену, но не будете предоставлять его через API.

Другими словами: делайте это с помощью шаблонов Django, а не через диспетчер URL. Так гораздо безопаснее.

1 голос
/ 28 сентября 2008

Отмените это, я был неправ. (См. Комментарии.) Вы можете предотвратить эксплойт, убедившись, что ваш JSON соответствует спецификации: всегда убедитесь, что вы возвращаете литерал объекта в качестве объекта верхнего уровня. (Я не могу гарантировать, что дальнейших действий не будет. Представьте, что браузер предоставляет доступ к ошибочному коду в своих событиях window.onerror!)

Вы не можете полагаться на правила межсайтового скриптинга, чтобы сохранять конфиденциальность ответов AJAX. Например, если вы возвращаете маркер CSRF как JSON, вредоносный сайт может переопределить конструктор String или Array и запросить ресурс.

bigmattyh правильно: вам нужно вставить токен где-нибудь в разметку. В качестве альтернативы, вы можете отклонить любые сообщения POST, которые do имеют реферер, который не не соответствует. Таким образом, только люди с чрезмерно усердными программными брандмауэрами будут уязвимы для CSRF.

...