Безопасность в Django
Этот документ является обзором функций безопасности Django. Он включает рекомендации по обеспечению безопасности сайта, работающего на Django.
Защита от межсайтовых скриптов (XSS)
Атаки XSS позволяют пользователю вводить клиентские скрипты в браузеры других пользователей. Обычно это достигается путем хранения вредоносных скриптов в базе данных, откуда они будут извлечены и отображены другим пользователям, или путем получения от пользователей ссылки, которая заставит JavaScript злоумышленника выполниться в браузере пользователя. Однако атаки XSS могут исходить из любого ненадежного источника данных, такого как куки или веб-сервисы, всякий раз, когда данные не достаточно очищаются перед включением в страницу.
Использование шаблонов Django защищает вас от большинства атак XSS. Однако важно понимать, какую защиту они предоставляют и каковы их ограничения.
Шаблоны Django выводят экранированные специальные символы, которые особенно опасны для HTML. Хотя это защищает пользователей от большинства вредоносных входных данных, это не полностью надежно. Например, это не защитит от следующего:
<style class={{ var }}>...</style>
Если var установлено в 'class1 onmouseover=javascript:func()', это может привести к несанкционированному выполнению JavaScript в зависимости от того, как браузер отображает несовершенный HTML. (Для решения этой проблемы необходимо привести в соответствие значение атрибута.)
Также важно проявлять особую осторожность при использовании is_safe с пользовательскими тегами шаблонов, тега шаблона safe, mark_safe и при отключении автоматического экранирования.
Кроме того, если вы используете систему шаблонов для вывода чего-то, кроме HTML, могут потребоваться совершенно отдельные символы и слова, которые необходимо экранировать.
Также следует проявлять крайнюю осторожность при хранении HTML в базе данных, особенно когда этот HTML извлекается и отображается.
Защита от межсайтовых поддельных запросов (CSRF)
Атаки CSRF позволяют злоумышленнику выполнять действия с учетными данными другого пользователя без его ведома или согласия.
Django имеет встроенную защиту от большинства типов атак CSRF, если вы включили и использовали её где необходимо. Однако, как и в случае с любой техникой смягчения, существуют ограничения. Например, можно отключить модуль CSRF глобально или для определенных представлений. Вы должны делать это только в том случае, если вы знаете, что делаете. Есть и другие ограничения, если ваш сайт имеет поддомены, которые находятся вне вашего контроля.
Защита от CSRF работает путем проверки секрета в каждом запросе POST. Это гарантирует, что злоумышленник не может просто «переиграть» POST-запрос формы на ваш веб-сайт и заставить другого вошедшего в систему пользователя незаметно отправить эту форму. Злоумышленнику необходимо знать секрет, который специфичен для пользователя (используя cookie).
При развертывании с HTTPS, CsrfViewMiddleware будет проверять, что заголовок HTTP referer установлен на URL на том же домене (включая поддомен и порт). Поскольку HTTPS обеспечивает дополнительную безопасность, крайне важно обеспечить использование HTTPS, если оно доступно, перенаправляя запросы на небезопасные соединения и используя HSTS для поддерживаемых браузеров.
Будьте очень осторожны с маркировкой представлений декоратором csrf_exempt , если это не абсолютно необходимо.
Защита от инъекций SQL
SQL-инъекция — это тип атаки, при котором злоумышленник может выполнить произвольный SQL-код в базе данных. Это может привести к удалению записей или утечке данных.
Запросы Django защищены от инъекций SQL, так как их запросы строятся с использованием параметризации запросов. SQL-код запроса определяется отдельно от параметров запроса. Поскольку параметры могут быть предоставлены пользователем и, следовательно, небезопасны, они экранируются соответствующим драйвером базы данных.
Django также предоставляет разработчикам возможность писать сырые запросы или выполнять пользовательский SQL. Эти возможности следует использовать с осторожностью, и вы всегда должны быть внимательны, чтобы правильно экранировать любые параметры, которые могут контролироваться пользователем. Кроме того, следует проявлять осторожность при использовании extra() и RawSQL.
Защита от кликджекинга
Кликджекинг — это тип атаки, при которой вредоносный сайт обрамляет другой сайт в фрейм. Эта атака может привести к тому, что неосведомлённый пользователь будет обманут на выполнение непреднамеренных действий на целевом сайте.
Django содержит защиту от кликджекинга в виде X-Frame-Options middleware, который в поддерживающих браузерах может предотвратить отображение сайта внутри фрейма. Возможна отключение защиты на уровне представления или конфигурация точного значения заголовка, отправляемого.
Средство рекомендуется для любого сайта, которому не требуется, чтобы страницы были вложены в фрейм сторонними сайтами, или для которого требуется разрешить это только для небольшой части сайта.
SSL/HTTPS
Для повышения безопасности всегда лучше развернуть ваш сайт через HTTPS. Без этого злоумышленники в сети могут перехватывать учетные данные аутентификации или любую другую информацию, передаваемую между клиентом и сервером, а в некоторых случаях — активные злоумышленники — изменять данные, отправляемые в любом направлении.
Если вы хотите получить защиту, предоставляемую HTTPS, и включили ее на вашем сервере, вам могут потребоваться дополнительные шаги:
- При необходимости установите
SECURE_PROXY_SSL_HEADER, убедившись, что вы полностью поняли предупреждения там. Невыполнение этого может привести к уязвимостям CSRF, а неправильное выполнение также опасно! -
Установите
SECURE_SSL_REDIRECTвTrue, чтобы запросы через HTTP перенаправлялись на HTTPS.Обратите внимание на замечания под
SECURE_PROXY_SSL_HEADER. В случае обратного прокси, может быть проще или безопаснее настроить основной веб-сервер для перенаправления на HTTPS. -
Используйте «защищенные» cookie.
Если браузер первоначально подключается через HTTP, что является стандартным для большинства браузеров, возможна утечка существующих cookie. По этой причине вы должны установить значения
SESSION_COOKIE_SECUREиCSRF_COOKIE_SECUREвTrue. Это указывает браузеру отправлять эти cookie только по HTTPS-соединениям. Обратите внимание, что это означает, что сессии не будут работать через HTTP, и защита от CSRF будет предотвращать принятие данных POST через HTTP (что будет нормально, если вы перенаправляете весь трафик HTTP на HTTPS). -
Используйте HTTP Strict Transport Security (HSTS)
HSTS — это заголовок HTTP, который сообщает браузеру, что все будущие соединения с определенным сайтом всегда должны использовать HTTPS. В сочетании с перенаправлением запросов через HTTP на HTTPS это гарантирует, что соединения всегда будут пользоваться дополнительной безопасностью SSL при условии, что произойдет одно успешное соединение. HSTS может быть настроен с помощью
SECURE_HSTS_SECONDS,SECURE_HSTS_INCLUDE_SUBDOMAINSиSECURE_HSTS_PRELOAD, или на веб-сервере.
Валидация заголовков Host
Django использует заголовок Host, предоставленный клиентом, для построения URL-адресов в некоторых случаях. Хотя эти значения очищаются для предотвращения атак межсайтовых скриптов, поддельное значение 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), если ваша конфигурация этого требует.
Безопасность сессий
Аналогично ограничениям CSRF, требующим, чтобы сайт был развернут таким образом, что недоверенные пользователи не имели доступа к каким-либо поддоменам, django.contrib.sessions также имеет ограничения. Подробности см. в разделе руководства по сессиям о безопасности.
Безопасность содержимого, загруженного пользователем
Примечание
Рассмотрите возможность обслуживания статических файлов с облачного сервиса или CDN, чтобы избежать некоторых из этих проблем.
- Если ваш сайт принимает загрузку файлов, настоятельно рекомендуется ограничить эти загрузки на уровне конфигурации веб-сервера разумным размером, чтобы предотвратить атаки типа отказа в обслуживании (DoS). В Apache это можно легко установить с помощью директивы LimitRequestBody.
- Если вы обслуживаете собственные статические файлы, убедитесь, что обработчики, такие как
mod_phpв Apache, которые бы выполняли статические файлы как код, отключены. Вы не хотите, чтобы пользователи могли выполнить произвольный код, загрузив и запросив специально подготовленный файл. -
Обработка загрузки медиафайлов Django создаёт некоторые уязвимости, когда эти медиафайлы обслуживаются способами, не соответствующими лучшим практикам безопасности. В частности, HTML-файл можно загрузить как изображение, если этот файл содержит действительный заголовок PNG, после которого следует вредоносный HTML. Этот файл пройдёт проверку библиотеки, которую Django использует для
ImageFieldобработки изображений (Pillow). Когда этот файл впоследствии отображается пользователю, он может отображаться как HTML в зависимости от типа и конфигурации вашего веб-сервера.В рамках фреймворка нет технического решения, гарантирующего безопасную проверку всего содержимого загружаемых пользователем файлов, однако существуют другие шаги, которые вы можете предпринять, чтобы смягчить эти атаки:
- Один класс атак можно предотвратить, всегда обслуживая контент, загруженный пользователем, с отдельного верхнего или второго уровня домена. Это предотвращает любые эксплойты, блокируемые политикой одинакового происхождения, такими как межсайтовый скриптинг. Например, если ваш сайт работает на
example.com, вы хотели бы обслуживать загружаемый контент (настройкаMEDIA_URL) с чего-то вродеusercontent-example.com. Недостаточно обслуживать контент с поддомена, например,usercontent.example.com. - Помимо этого, приложения могут определить белый список разрешенных расширений файлов для загружаемых пользователем файлов и настроить веб-сервер на обслуживание только таких файлов.
- Один класс атак можно предотвратить, всегда обслуживая контент, загруженный пользователем, с отдельного верхнего или второго уровня домена. Это предотвращает любые эксплойты, блокируемые политикой одинакового происхождения, такими как межсайтовый скриптинг. Например, если ваш сайт работает на
Дополнительные темы безопасности
Хотя Django предоставляет хорошую защиту по умолчанию, всё же важно правильно развернуть ваше приложение и воспользоваться защитой веб-сервера, операционной системы и других компонентов.
- Убедитесь, что ваш Python-код находится вне корня веб-сервера. Это гарантирует, что ваш Python-код не будет случайно обслуживаться как обычный текст (или случайно выполняться).
- Обращайте внимание на любые файлы, загруженные пользователем.
- Django не ограничивает запросы для проверки подлинности пользователей. Для защиты от атак методом перебора паролей против системы проверки подлинности вы можете рассмотреть возможность развертывания плагина Django или модуля веб-сервера для ограничения этих запросов.
- Храните ваш
SECRET_KEYв секрете. - Рекомендуется ограничить доступ к вашей системе кэширования и базе данных с помощью брандмауэра.
- Ознакомьтесь со списком OWASP (Open Web Application Security Project) Top 10, который определяет некоторые распространённые уязвимости веб-приложений. Хотя Django имеет инструменты для решения некоторых проблем, другие проблемы необходимо учитывать при проектировании вашего проекта.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.2/topics/security/