Защита от вредоносных воздействий в 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 и при отключенном autoescape.
Кроме того, если вы используете систему шаблонов для вывода чего-то кроме 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, которое в поддерживаемом браузере может предотвратить отображение сайта внутри фрейма. Возможно отключить защиту на уровне отдельных представлений или настроить точное значение отправляемого заголовка.
Этот middleware настоятельно рекомендуется для любых сайтов, которые не должны отображаться в фреймах третьих сторон или которым требуется это только для небольшой части сайта.
SSL/HTTPS
Для обеспечения безопасности всегда лучше развертывать свой сайт с использованием HTTPS. Без этого злоумышленники в сети могут перехватывать учетные данные аутентификации или любую другую информацию, передаваемую между клиентом и сервером, а в некоторых случаях — активные злоумышленники — могут изменять данные, передаваемые в любом направлении.
Если вы хотите воспользоваться преимуществами защиты HTTPS и активировали его на своем сервере, вам могут потребоваться дополнительные шаги:
- При необходимости установите
SECURE_PROXY_SSL_HEADER, убедившись, что вы полностью поняли предупреждения. Невыполнение этого может привести к уязвимостям CSRF, а неправильное выполнение — к опасности! -
Установите
SECURE_SSL_REDIRECTнаTrue, чтобы запросы через HTTP перенаправлялись на HTTPS.Обратите внимание на замечания в разделе
SECURE_PROXY_SSL_HEADER. В случае с обратным прокси-сервером может быть проще или безопаснее настроить основной веб-сервер на перенаправление на HTTPS. -
Используйте «защищенные» куки.
Если браузер первоначально подключается через 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, или на уровне веб-сервера.
Валидация заголовков хоста
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), если это необходимо вашей конфигурации.
Политика переадресации
Браузеры используют Referer заголовок в качестве способа отправки информации на сайт о том, как пользователи попали на него. Установив политику переадресации, вы можете помочь защитить конфиденциальность своих пользователей, ограничивая случаи, когда устанавливается Referer заголовок. Подробности см. в разделе политики переадресации в справке по среднему обеспечению безопасности.
Политика открывания междоменных запросов
Заголовок политики открывания междоменных запросов (COOP) позволяет браузерам изолировать окно верхнего уровня от других документов, помещая их в различную группу контекстов, чтобы они не могли напрямую взаимодействовать с окном верхнего уровня. Если документ, защищённый COOP, открывает всплывающее окно междоменного запроса, свойство window.opener всплывающего окна будет null. COOP защищает от атак междоменного запроса. Подробности см. в разделе политики открывания междоменных запросов в справке по среднему обеспечению безопасности.
Безопасность сеансов
Аналогично ограничениям CSRF, требующим, чтобы сайт был развернут таким образом, чтобы недоверенные пользователи не имели доступа к каким-либо доменам, django.contrib.sessions также имеет ограничения. Подробности см. в разделе руководства по теме сеансов о безопасности.
Безопасность контента, загружаемого пользователем
Примечание
Рассмотрите обслуживание статических файлов с облачного сервиса или CDN, чтобы избежать некоторых из этих проблем.
- Если ваш сайт принимает загрузку файлов, настоятельно рекомендуется ограничить эти загрузки разумным размером в конфигурации веб-сервера, чтобы предотвратить атаки типа «отказ в обслуживании» (DOS). В Apache это можно легко задать с помощью директивы LimitRequestBody.
- Если вы обслуживаете свои собственные статические файлы, убедитесь, что обработчики, такие как
mod_php, которые выполняют статические файлы как код, отключены. Вы не хотите, чтобы пользователи могли выполнять произвольный код, загружая и запрашивая специально созданный файл. -
Обработка загрузки медиафайлов 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иSECRET_KEY_FALLBACKS(если используется) в секрете. - Хорошо ограничить доступ к вашей системе кэширования и базе данных с помощью брандмауэра.
- Посмотрите на список 10 основных уязвимостей веб-приложений Open Web Application Security Project (OWASP) здесь, в котором указаны некоторые распространённые уязвимости веб-приложений. Хотя Django имеет инструменты для решения некоторых из них, другие проблемы необходимо учитывать при разработке вашего проекта.
- Mozilla обсуждает различные темы, касающиеся безопасности веб-приложений. Их страницы также содержат принципы безопасности, которые применимы к любой системе.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/topics/security/