Безопасность в Django

Этот документ представляет собой обзор функций безопасности Django. Он включает советы по обеспечению безопасности сайта, работающего на Django.

Защита от межсайтовых скриптов (XSS)

XSS attacks allow a user to inject client side scripts into the browsers of other users. This is usually achieved by storing the malicious scripts in the database where it will be retrieved and displayed to other users, or by getting users to click a link which will cause the attacker’s JavaScript to be executed by the user’s browser. However, XSS attacks can originate from any untrusted source of data, such as cookies or web services, whenever the data is not sufficiently sanitized before including in a page.

Использование шаблонов Django защищает вас от большинства XSS-атак. Однако важно понимать, какую защиту оно обеспечивает и каковы его ограничения.

Django шаблоны escape specific characters, которые особенно опасны для HTML. Хотя это защищает пользователей от большинства вредоносных вводимых данных, это не совсем надежно. Например, это не защитит следующее:

<style class={{ var }}>...</style>

Если var установлено в 'class1 onmouseover=javascript:func()', это может привести к несанкционированному выполнению JavaScript, в зависимости от того, как браузер отображает несовершенный HTML. (Цитирование значения атрибута исправит этот случай).

Также важно быть особенно осторожным при использовании is_safe с пользовательскими тегами шаблонов, тегом шаблона safe, mark_safe, а также при выключенном автоскейпе.

Кроме того, если вы используете систему шаблонов для вывода чего-то, отличного от HTML, могут существовать совершенно отдельные символы и слова, требующие экранирования.

Вы также должны быть очень осторожны при хранении HTML в базе данных, особенно когда этот HTML извлекается и отображается.

Защита от подделки межсайтовых запросов (CSRF)

Атаки CSRF позволяют злоумышленнику выполнить действия, используя учетные данные другого пользователя без его ведома или согласия.

Django имеет встроенную защиту от большинства типов CSRF-атак, при условии, что вы указываете enabled and used it там, где это необходимо. Однако, как и у любой техники защиты, здесь есть свои ограничения. Например, можно отключить модуль CSRF глобально или для определенных представлений. Делать это следует только в том случае, если вы знаете, что делаете. Есть и другие limitations, если ваш сайт имеет поддомены, которые находятся вне вашего контроля.

CSRF protection works путем проверки наличия секрета в каждом POST-запросе. Это гарантирует, что злоумышленник не сможет «воспроизвести» форму POST на вашем сайте и заставить другого вошедшего пользователя невольно отправить эту форму. Вредоносный пользователь должен знать секрет, который зависит от конкретного пользователя (с помощью cookie).

При развертывании с HTTPS, CsrfViewMiddleware будет проверять, что заголовок HTTP referer установлен на URL того же происхождения (включая поддомен и порт). Поскольку HTTPS обеспечивает дополнительную безопасность, необходимо убедиться, что соединения используют HTTPS там, где он доступен, переадресуя запросы небезопасных соединений и используя HSTS для поддерживаемых браузеров.

Будьте очень осторожны с маркировкой представлений декоратором csrf_exempt, если это не является абсолютно необходимым.

Защита от SQL-инъекций

SQL-инъекция - это тип атаки, при которой злоумышленник может выполнить произвольный SQL-код в базе данных. Это может привести к удалению записей или утечке данных.

Наборы запросов Django защищены от SQL-инъекций, поскольку их запросы строятся с использованием параметризации запросов. SQL-код запроса определяется отдельно от параметров запроса. Поскольку параметры могут быть предоставлены пользователем и поэтому небезопасны, они экранируются базовым драйвером базы данных.

Django также дает разработчикам возможность написать raw queries или выполнить custom sql. Эти возможности следует использовать экономно, и вы всегда должны быть осторожны, чтобы правильно экранировать любые параметры, которыми может управлять пользователь. Кроме того, следует проявлять осторожность при использовании extra() и RawSQL.

Защита от кликджекинга

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

Django содержит clickjacking protection в виде X-Frame-Options middleware, который в поддерживающем браузере может предотвратить отображение сайта внутри фрейма. Можно отключить защиту для каждого вида или настроить точное значение передаваемого заголовка.

Это промежуточное ПО настоятельно рекомендуется для любого сайта, которому не нужно, чтобы его страницы были заключены во фрейм сторонними сайтами, или нужно разрешить это только для небольшой части сайта.

SSL/HTTPS

С точки зрения безопасности всегда лучше развернуть свой сайт на HTTPS. Без этого злоумышленники могут подсмотреть учетные данные аутентификации или любую другую информацию, передаваемую между клиентом и сервером, а в некоторых случаях - активные сетевые злоумышленники - изменить данные, передаваемые в любом направлении.

Если вам нужна защита, которую обеспечивает HTTPS, и вы включили ее на своем сервере, вам могут понадобиться некоторые дополнительные шаги:

  • Если необходимо, установите SECURE_PROXY_SSL_HEADER, убедившись, что вы хорошо поняли содержащиеся там предупреждения. Невыполнение этого требования может привести к CSRF-уязвимости, а неправильное выполнение может быть опасным!

  • Установите SECURE_SSL_REDIRECT в True, чтобы запросы по HTTP перенаправлялись на HTTPS.

    Please note the caveats under SECURE_PROXY_SSL_HEADER. For the case of a reverse proxy, it may be easier or more secure to configure the main web server to do the redirect to HTTPS.

  • Используйте «безопасные» файлы cookie.

    Если браузер изначально подключается через HTTP, что является стандартным для большинства браузеров, возможна утечка существующих файлов cookie. По этой причине следует установить настройки SESSION_COOKIE_SECURE и CSRF_COOKIE_SECURE на True. Это даст браузеру указание отправлять эти куки только через HTTPS-соединения. Обратите внимание, что это означает, что сессии не будут работать через HTTP, а защита CSRF не позволит принимать любые данные POST через HTTP (что будет нормально, если вы перенаправляете весь HTTP-трафик на HTTPS).

  • Используйте Строгая транспортная безопасность HTTP (HSTS)

    HSTS is an HTTP header that informs a browser that all future connections to a particular site should always use HTTPS. Combined with redirecting requests over HTTP to HTTPS, this will ensure that connections always enjoy the added security of SSL provided one successful connection has occurred. HSTS may either be configured with SECURE_HSTS_SECONDS, SECURE_HSTS_INCLUDE_SUBDOMAINS, and SECURE_HSTS_PRELOAD, or on the web server.

Проверка заголовка хоста

Django использует заголовок Host, предоставляемый клиентом, для построения URL в определенных случаях. Хотя эти значения санируются для предотвращения атак Cross Site Scripting, поддельное значение Host может быть использовано для подделки межсайтовых запросов, атак отравления кэша и отравления ссылок в электронных письмах.

Поскольку даже кажущиеся безопасными конфигурации веб-серверов восприимчивы к поддельным заголовкам Host, Django проверяет Host заголовки против ALLOWED_HOSTS настроек в методе django.http.HttpRequest.get_host().

Эта проверка применяется только через get_host(); если ваш код обращается к заголовку Host непосредственно из request.META, вы обходите эту защиту.

Для получения более подробной информации смотрите полную документацию ALLOWED_HOSTS.

Предупреждение

В предыдущих версиях этого документа рекомендовалось настроить веб-сервер таким образом, чтобы он проверял входящие заголовки HTTP Host. Хотя это по-прежнему рекомендуется, во многих распространенных веб-серверах конфигурация, которая, как кажется, проверяет заголовок Host, на самом деле может этого не делать. Например, даже если Apache настроен так, что ваш сайт Django обслуживается с виртуального хоста не по умолчанию с установленным ServerName, все равно возможно, что HTTP запрос будет соответствовать этому виртуальному хосту и предоставит поддельный заголовок Host. Таким образом, Django теперь требует, чтобы вы явно установили ALLOWED_HOSTS, а не полагались на конфигурацию веб-сервера.

Кроме того, Django требует, чтобы вы явно включили поддержку заголовка X-Forwarded-Host (через параметр USE_X_FORWARDED_HOST), если ваша конфигурация требует этого.

Политика в отношении рефералов

Браузеры используют заголовок Referer как способ отправки информации на сайт о том, как пользователи попали на него. Установив политику Referrer Policy, вы можете помочь защитить конфиденциальность ваших пользователей, ограничив, при каких обстоятельствах устанавливается заголовок Referer. Подробнее см. в разделе the referrer policy section of the security middleware reference.

Политика кросс-оригинального открытия

Заголовок cross-origin opener policy (COOP) позволяет браузерам изолировать окно верхнего уровня от других документов, помещая их в другую контекстную группу, чтобы они не могли напрямую взаимодействовать с окном верхнего уровня. Если документ, защищенный COOP, открывает кросс-оригинальное всплывающее окно, свойство window.opener всплывающего окна будет null. COOP защищает от кросс-оригинальных атак. Подробности см. в разделе the cross-origin opener policy section of the security middleware reference.

Безопасность сеанса

Подобно CSRF limitations, требующему развертывания сайта таким образом, чтобы недоверенные пользователи не имели доступа к поддоменам, django.contrib.sessions также имеет ограничения. Подробнее см. в the session topic guide section on security.

Загружаемый пользователем контент

Примечание

Рассмотрим serving static files from a cloud service or CDN, чтобы избежать некоторых из этих проблем.

  • If your site accepts file uploads, it is strongly advised that you limit these uploads in your web server configuration to a reasonable size in order to prevent denial of service (DOS) attacks. In Apache, this can be easily set using the LimitRequestBody directive.

  • Если вы обслуживаете собственные статические файлы, убедитесь, что такие обработчики, как mod_php Apache, которые выполняют статические файлы как код, отключены. Вы же не хотите, чтобы пользователи могли выполнить произвольный код, загрузив и запросив специально созданный файл.

  • Обработка загрузки мультимедиа в Django создает некоторые уязвимости, когда это мультимедиа обслуживается способами, не соответствующими лучшим практикам безопасности. В частности, HTML-файл может быть загружен как изображение, если этот файл содержит правильный заголовок PNG, за которым следует вредоносный HTML. Этот файл пройдет проверку библиотеки, которую Django использует для ImageField обработки изображений (Pillow). Когда этот файл впоследствии отображается пользователю, он может отображаться как HTML в зависимости от типа и конфигурации вашего веб-сервера.

    На уровне фреймворка не существует надежного технического решения для безопасной проверки всего содержимого загружаемых пользователем файлов, однако есть некоторые другие шаги, которые вы можете предпринять для защиты от этих атак:

    1. Один класс атак можно предотвратить, если всегда обслуживать загруженный пользователем контент с отдельного домена верхнего или второго уровня. Это предотвращает любые атаки, блокируемые защитой same-origin policy, такие как межсайтовый скриптинг. Например, если ваш сайт работает на example.com, вы захотите обслуживать загружаемое содержимое (настройка MEDIA_URL) с чего-то вроде usercontent-example.com. Этого не достаточно, чтобы обслуживать содержимое с поддомена типа usercontent.example.com.
    2. Кроме того, приложения могут определить список допустимых расширений файлов для загружаемых пользователем файлов и настроить веб-сервер на обслуживание только таких файлов.

Дополнительные темы по безопасности

While Django provides good security protection out of the box, it is still important to properly deploy your application and take advantage of the security protection of the web server, operating system and other components.

  • Make sure that your Python code is outside of the web server’s root. This will ensure that your Python code is not accidentally served as plain text (or accidentally executed).
  • Будьте осторожны с любыми user uploaded files.
  • Django does not throttle requests to authenticate users. To protect against brute-force attacks against the authentication system, you may consider deploying a Django plugin or web server module to throttle these requests.
  • Keep your SECRET_KEY, and SECRET_KEY_FALLBACKS if in use, secret.
  • Хорошей идеей будет ограничить доступ к системе кэширования и базе данных с помощью брандмауэра.
  • Ознакомьтесь с проектом Open Web Application Security Project (OWASP) Top 10 list, который определяет некоторые распространенные уязвимости в веб-приложениях. Хотя Django имеет инструменты для решения некоторых из этих проблем, другие проблемы должны быть учтены при разработке вашего проекта.
  • Mozilla обсуждает различные темы, касающиеся web security. На их страницах также представлены принципы безопасности, применимые к любой системе.
Вернуться на верх