Безопасность в 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 будет корректно экранирован драйвером базы данных. Однако Django также предоставляет разработчикам возможность писать сырые запросы или выполнять пользовательский SQL. Эти возможности следует использовать с осторожностью, и вы всегда должны следить за тем, чтобы все параметры, которые пользователь может контролировать, были должным образом экранированы. Кроме того, следует проявлять осторожность при использовании extra() и RawSQL.
Защита от clickjacking
Clickjacking — это тип атаки, при которой злоумышленный сайт включает другой сайт в фрейм. Эта атака может привести к тому, что неосведомленный пользователь будет обманут, выполняя нежелательные действия на целевом сайте.
Django содержит защиту от clickjacking в виде 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или на веб-сервере.
Проверка заголовков хоста
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, которые выполняют статические файлы как код, отключены. Вы не хотите, чтобы пользователи могли выполнять произвольный код, загружая и запрашивая специально составленный файл. -
Обработка загрузок медиа-файлов Django создаёт уязвимости, когда эти медиа-файлы обслуживаются способами, не соответствующими рекомендациям по безопасности. В частности, HTML-файл можно загрузить как изображение, если этот файл содержит допустимый заголовок PNG, за которым следует вредоносный HTML. Этот файл пройдёт проверку библиотеки, которую Django использует для обработки изображений
ImageField(Pillow). Когда этот файл впоследствии отображается пользователю, он может отображаться как HTML, в зависимости от типа и конфигурации вашего веб-сервера.Не существует технического решения, гарантирующего безопасность на уровне фреймворка, для проверки всего загруженного пользователем контента, однако существуют шаги для смягчения этих атак:
- Один класс атак можно предотвратить, всегда обслуживая загруженный пользователем контент с отдельного домена верхнего или второго уровня. Это предотвращает эксплойты, блокируемые политикой "одинакового происхождения" (Same-origin policy), такими как межсайтовый скриптинг. Например, если ваш сайт работает на
example.com, вы хотели бы обслуживать загруженный контент (параметрMEDIA_URL) с помощью чего-то вродеusercontent-example.com. Недостаточно обслуживать контент с поддомена, такого какusercontent.example.com. - Помимо этого, приложения могут определить белый список допустимых расширений файлов для загружаемых пользователем файлов и настроить веб-сервер на обслуживание только таких файлов.
- Один класс атак можно предотвратить, всегда обслуживая загруженный пользователем контент с отдельного домена верхнего или второго уровня. Это предотвращает эксплойты, блокируемые политикой "одинакового происхождения" (Same-origin policy), такими как межсайтовый скриптинг. Например, если ваш сайт работает на
Дополнительные темы безопасности
Хотя Django предоставляет хорошую защиту по умолчанию, всё ещё важно правильно развёртывать ваше приложение и использовать защитные механизмы веб-сервера, операционной системы и других компонентов.
- Убедитесь, что ваш Python-код находится вне корневого каталога веб-сервера. Это гарантирует, что ваш Python-код не будет случайно обслуживаться как простой текст (или случайно выполняться).
- Обращайте внимание на любые загружаемые пользователем файлы.
- Django не ограничивает запросы для проверки подлинности пользователей. Для защиты от атак методом перебора паролей против системы проверки подлинности, вы можете рассмотреть возможность развертывания плагина Django или модуля веб-сервера для ограничения этих запросов.
- Сохраните
SECRET_KEYв секрете. - Рекомендуется ограничить доступ к вашей системе кэширования и базе данных с помощью брандмауэра.
- Ознакомьтесь со списком 10 самых распространённых уязвимостей веб-приложений от Open Web Application Security Project (OWASP) Top 10, который определяет некоторые распространённые уязвимости веб-приложений. Хотя Django имеет инструменты для решения некоторых проблем, другие проблемы необходимо учитывать при проектировании вашего проекта.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.10/topics/security/