Безопасность в Django
Данный документ содержит обзор функций безопасности Django. Он включает рекомендации по обеспечению безопасности сайта, работающего на Django.
Защита от межсайтовых сценариев (XSS)
Атаки XSS позволяют пользователю внедрять скрипты на стороне клиента в браузеры других пользователей. Обычно это достигается путем хранения вредоносных скриптов в базе данных, откуда они извлекаются и отображаются другим пользователям, или путем заманивания пользователей в клик по ссылке, которая заставит JavaScript злоумышленника выполниться в браузере пользователя. Однако атаки XSS могут происходить из любого ненадежного источника данных, такого как куки или веб-сервисы, когда данные недостаточно очищаются перед включением в страницу.
Использование шаблонов Django защищает вас от большинства атак XSS. Однако важно понимать, какую защиту они предоставляют, и какие у них ограничения.
Шаблоны Django экранируют определенные символы, которые особенно опасны для HTML. Хотя это защищает пользователей от большинства вредоносных входных данных, это не полностью надежно. Например, это не защитит от следующего:
Если var установлено в 'class1 onmouseover=javascript:func()', это может привести к несанкционированному выполнению JavaScript, в зависимости от того, как браузер отображает неполный HTML. (Цитата значения атрибута решит эту проблему.)
Также важно проявлять особую осторожность при использовании is_safe с пользовательскими тегами шаблонов, тегом шаблона safe, mark_safe, и когда автоматическое экранирование выключено.
Кроме того, если вы используете систему шаблонов для вывода чего-то кроме HTML, могут потребоваться экранирование совершенно других символов и слов.
Следует также проявлять особую осторожность при хранении HTML в базе данных, особенно когда этот HTML извлекается и отображается.
Защита от межсайтовых поддельных запросов (CSRF)
Атаки CSRF позволяют злоумышленнику выполнить действия с использованием учетных данных другого пользователя без его ведома или согласия.
Django имеет встроенную защиту от большинства типов атак CSRF, если вы включили и использовали её где это необходимо. Однако, как и любая методика смягчения, у неё есть ограничения. Например, вы можете отключить модуль CSRF глобально или для определенных представлений. Вы должны это делать только в том случае, если знаете, что делаете. Существуют другие ограничения, если ваш сайт имеет поддомены, которые вы не контролируете.
Защита CSRF работает путем проверки nonce в каждом запросе POST. Это гарантирует, что злоумышленник не может просто «воспроизвести» форму POST на вашем веб-сайте и незаметно для другого пользователя отправить эту форму. Злоумышленник должен знать nonce, который является специфичным для пользователя (используя куки).
При развертывании с HTTPS, CsrfViewMiddleware будет проверять, что заголовок HTTP referer установлен на URL в том же источнике (включая поддомен и порт). Поскольку HTTPS предоставляет дополнительную безопасность, необходимо гарантировать, что соединения используют HTTPS, где это возможно, перенаправляя запросы небезопасных соединений и используя HSTS для поддерживаемых браузеров.
Будьте очень осторожны при маркировке представлений с помощью декоратора csrf_exempt если это не абсолютно необходимо.
Защита от инъекции SQL
Инъекция SQL — это тип атаки, при которой злоумышленник может выполнить произвольный SQL-код в базе данных. Это может привести к удалению записей или утечке данных.
Используя наборы запросов Django, результирующий 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или на веб-сервере.
Проверка заголовков хоста
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, а не полагается на конфигурацию веб-сервера.
Кроме того, начиная с версии 1.3.1, Django требует явного включения поддержки заголовка X-Forwarded-Host (через настройку USE_X_FORWARDED_HOST), если ваша конфигурация этого требует.
Безопасность сессий
Аналогично ограничениям 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в секрете. - Рекомендуется ограничить доступ к вашей системе кэширования и базе данных с помощью брандмауэра.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.8/topics/security/