Безопасность в 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 на ваш сайт и заставить другого вошедшего в систему пользователя незаметно отправить эту форму. Злоумышленник должен знать секретный ключ, который является уникальным для каждого пользователя (используя куки).
При развертывании с 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. -
Используйте «защищенные» куки.
Если браузер изначально подключается через HTTP, что является стандартным для большинства браузеров, возможна утечка существующих куки. Поэтому вы должны установить свои настройки
SESSION_COOKIE_SECUREиCSRF_COOKIE_SECUREв значениеTrue. Это указывает браузеру отправлять эти куки только по 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), если ваша конфигурация это требует.
Политика переадресации
Браузеры используют Referer заголовок в качестве способа отправки информации на сайт о том, как пользователи туда попали. Установив Политику переадресации, вы можете помочь защитить конфиденциальность своих пользователей, ограничив условия, при которых устанавливается Referer заголовок. Подробности см. в разделе политики переадресации справочника по middleware безопасности.
Безопасность сеансов
Аналогично ограничениям CSRF, требующим размещения сайта таким образом, чтобы неавторизованные пользователи не имели доступа к каким-либо поддоменам, django.contrib.sessions также имеет ограничения. Подробности см. в разделе руководства по сеансам о безопасности.
Безопасность загружаемого пользователем контента
Примечание
Рассмотрите обслуживание статических файлов с помощью облачного сервиса или CDN, чтобы избежать некоторых проблем.
- Если ваш сайт принимает загрузки файлов, настоятельно рекомендуется ограничить эти загрузки разумным размером в конфигурации вашего веб-сервера, чтобы предотвратить атаки типа «отказ в обслуживании» (DoS). В Apache это можно легко настроить с помощью директивы LimitRequestBody.
- Если вы обслуживаете свои статические файлы, убедитесь, что обработчики, такие как
mod_phpApache, которые выполняют статические файлы как код, отключены. Вы не хотите, чтобы пользователи могли выполнять произвольный код, загружая и запрашивая специально составленный файл. -
Обработка загрузки медиафайлов 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 Top 10 (Open Web Application Security Project), который определяет некоторые распространённые уязвимости веб-приложений. Хотя Django имеет инструменты для решения некоторых проблем, другие проблемы необходимо учитывать при проектировании вашего проекта.
- Mozilla рассматривает различные темы, касающиеся безопасности веб-приложений. Их страницы также содержат принципы безопасности, которые применяются к любой системе.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.0/topics/security/