Пакет django.contrib.csrf защищает от атак типа «подделка HTTP запросов» (Cross-Site Request Forgery), далее CSRF.
CSRF, также известная как «session riding» FIXME, является дырой в системе безопасности веб сайта. Она случается когда вредоносный сайт заставляет пользователя, незаметно для него, загрузить URL с сайта, на котором пользователь уже авторизован. Это непросто понять сначала, поэтому мы разберём пару примеров.
Допустим вы зашли в свою почту на сайте example.com. Интерфейс почтовой системы имеет кнопку Log out, которая вызывает URL example.com/logout. Таким образом для того, чтобы выйти из своей почты достаточно посетить страницу example.com/logout.
Вредоносный сайт может заставить вас посетить URL example.com/logout с помощью скрытого тега <iframe> на своей странице. Таким образом, если вы были авторизованы на почтовом интерфейсе example.com и посетили вредоносную страницу, которая выполнила через <iframe> обращение к example.com/logout, ваша авторизация на почтовом интерфейсе будет прекращена.
Очевидно, что выход из почтового интерфейса вопреки вашей воли не является ужасающем нарушением безопасности, но этот же подход может использоваться для любого сайта, который «доверяет» своим посетителям, например, сайт банка или электронного алгоритма.
В предыдущем примере сайт example.com был частично скомпрометирован, потому что он позволял изменять состояние (т.е. отменять авторизацию пользователя) через GET запрос. Более практично требовать POST запрос для изменения состояния на сайте. Но даже это не спасёт полностью от CSRF.
Предположим, что на сайте example.com провели обновление функциональность и теперь для отмены авторизации пользователя требуется нажать кнопку на форме, которая отправит POST запрос к example.com/logout. Более того, форма содержит скрытое поле:
<input type="hidden" name="confirm" value="true" />
Это даёт гарантию, что обычный POST запрос к
example.com/logout не отменит авторизацию
пользователя, для этого ещё должна передаваться переменная
confirm со значением true.
Несмотря на дополнительную безопасность этот механизм всё ещё может быть скомпрометирован CSRF — вредоносной странице просто потребуется сделать чуть больше работы. Атакующие могут создать целую форму для вашего сайта, спрятав её в невидимом <iframe>, а затем использовать JavaScript для автоматической отправки этой формы.
Как может ваш сайт защитить себя от этого типа атак? Первым шагом будет проверка того, что все GET запросы не содержат побочные эффекты. Затем, если вредоносный сайт включает одну из ваших страниц в <iframe>, это не будет приводить к негативному эффекту.
Остались POST запросы. Вторым шагом будет добавление в каждую форму скрытого поля, значение которого генерируется из идентификатора пользователя. Затем, при обработке формы на стороне сервера, следует проверять это поле и выдавать ошибку, если проверка не удастся.
Именно это и делает Django для предотвращения CSRF. А подробности далее.
Пакет django.contrib.csrf содержит только один модуль —
middleware.py. Модуль содержит класс
Django, CsrfMiddleware, которые
реализовывает защиту от CSRF.
Для активации защиты от CSRF следует добавить django.contrib.csrf.middleware.CsrfMiddleware в параметр MIDDLEWARE_CLASSES вашего файла конфигурации. Этот модуль нужен для обработки отклика после SessionMiddleware, таким образом CsrfMiddleware должен быть помещён до SessionMiddleware в списке (потому что классы при обработки отклика применяются от конца списка к началу). Также следует обрабатывать отклик до его компрессии или других изменений. Таким образом, CsrfMiddleware должно быть указано после GZipMiddleware. Обратитесь к секции «Порядок в MIDDLEWARE_CLASSES».
Если вам интересно, то вот как класс
CsrfMiddleware работает. Он делает
следующие две вещи:
Класс изменяет отклик с помощью добавления скрытого поля формы ко всем формам с методом POST. Поле имеет имя
csrfmiddlewaretoken, а значение является хэшем для идентификатора сессии плюс секретный ключ. Класс не изменяет отклик, в котором отсутствует идентификатор сессии, таким образом нет снижения производительности для запросов не использующих механизм сессий.Для всех POST запросов использующих механизм сессии класс производит проверку наличия и правильности
csrfmiddlewaretoken. Если такого поля у передаваемой формы нет, то пользователь получает ошибку 403, на которой написано: «Cross Site Request Forgery detected. Request aborted.»
Такой подход гарантирует, что будут приняты во внимание только формы с вашего сайта.
Данный класс умышленно нацелен только на POST запросы (и соответствующие формы с методами POST). Как мы объясняли, GET запросы не могут иметь побочных эффектов, проверить это — ваша задача.
POST запросы, не использующие механизм сессий, не защищаются. Их и не надо защищать, потому что вредоносные сайты могут выполнить такой запрос в любом случае.
Чтобы исключить внесение изменений в не-HTML запросы класс проверяет заголовок Content-Type отклика перед его модификацией. Только страницы с типами text/html или application/xml+xhtml подвергаются обработке.
Класс CsrfMiddleware требует наличия
механизма управления сессиями для своей работы. (Обратитесь
к разделу «Сессии, пользователи и регистрация» для
подробностей.) Если вы используете свой собственный механизм
управления сессиями или аутентификацией, которые изменяют
cookie сессий, данный класс вам не поможет.
Если ваше приложение создаёт HTML страницы и формы необычным
способом (т.е., если оно отправляет фрагменты HTML в
JavaScript оператор document.write), вы
можете пропустить фильтр, который добавляет скрытое поле к
форме. В этом случае отправка формы всегда будет
неудачна. (Это будет происходить, потому что класс
CsrfMiddleware использует регулярное
выражения для добавления поля
csrfmiddlewaretoken в ваш HTML перед
отправкой страницы клиенту, а регулярное выражение иногда не
может обработать уродский HTML.) Если вы предполагаете
возможность такой ситуации, просто просмотрите код в вашем
браузере и проверьте наличие поля
csrfmiddlewaretoken у формы.
Для получения информации по CSRF обратитесь к http://en.wikipedia.org/wiki/CSRF.
| Пред. | Уровень выше | След. |
| Перенаправления | Начало | Очеловечивание данных |
0 comments | Make a comment