Middleware для обеспечения безопасности в Django

Django предоставляет защитные механизмы от различных атак, но не все они включены по-умолчанию. В этом посте я хочу рассмотреть какие возможности по защите предоставляет Django и как их использовать.

django.middleware.security.SecurityMiddleware

Этот middleware включен по-умолчанию и должен быть самым первым в списке, для того чтобы злонамеренные запросы блокировались до обработки другими middleware.

Он защищает сразу от многих атак и каждую из этих защит можно включить/отключить отдельно используя переменные в settings.py:

server {
    # ...
    location /media/ {
        # ...
        add_header X-Content-Type-Options nosniff;
    }
}
server {
    listen 80;
    server_name  example.org;
    rewrite ^ http://example.org$request_uri? permanent;
}

Если при включении HSTS настроек заголовки не добавляются, возможно Django не распознает, что запросы зашифрованные из-за того, что располагается за реверс-прокси. Для того, чтобы Django понимал какие запросы были зашифрованными нужно добавить параметр SECURE_PROXY_SSL_HEADER в settings.py, который содержит кортеж ("header-name", "header-value"). Получив такой заголовок от прокси сервера Django будет считать что запрос был получен по протоколу HTTPS.

django.middleware.csrf.CsrfViewMiddleware

Middleware защищает от межсайтовой подделки запроса. При отправке любых небезопасных (POST, PUT, DELETE) запросов middleware будет проверять наличие csrf токена и если этот токен не найден или не корректен запрос будет фильтроваться. Для отправки токена существуют разные способы. Для обычных форм можно добавлять скрытое поле используя тег {% csrf_token %} в форме. Для ajax запросов можно добавлять заголовок X-CSRFToken со значением полученным из cookie.

Если у вас SPA и вы не используете {% csrf_token %}, то вам нужно заставить Django выдать клиенту cookie с токеном. Для этого можно использовать view decorator ensure_csrf_cookie.

django.middleware.clickjacking.XFrameOptionsMiddleware

При включении данный middleware добавляет заголовок X-Frame-Options: SAMEORIGIN, который запрещает современным браузерам загружать сайт в (i)frame на сайтах с другим доменом. Также можно запретить подключение сайта со всех доменов используя переменную X_FRAME_OPTIONS = 'DENY'.