Этот документ рассматривает возможности Django с точки зрения безопасности. В документе приведены советы по защите сайтов, созданных с помощью Django.
XSS атаки позволяют пользователю вставить собственные JS скрипты в браузеры других пользователей. Это достигается с помощью сохранения вредоносных скриптов в базе данных, которые затем запрашиваются и отображаются браузерами других пользователей, или принуждением пользователя нажать на ссылку, которая позволит вредоносному скрипту выполниться в браузере пользователя. Однако, 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 атаки позволяют недобросовестному пользователю выполнять действия от имени другого пользователя, без ведома последнего или его согласия.
Django обладает встроенной защитой против большинства типов CSRF атак, если вы активировали и использовали её там, где это необходимо. Однако, как это обычно бывает, существуют ограничения. Например, есть возможность отключить защиту CSRF глобально или на уровне отдельного представления. Такое можно делать, только если вы точно уверены в своих действиях. Существуют другие ограничения, если у вашего сайта есть поддомены, не находящиеся под вашим управлением.
CSRF защита работает, проверяя метку с текущим временем в каждом POST запросе. Она не позволяет злоумышленнику просто сформировать POST запрос формы к вашему сайту и создать возможность другому авторизованному пользователю нечаянно отправить эту форму. Злоумышленнику потребуется знать содержимое метки, которое сильно зависит от пользователя (используются куки).
Будьте очень внимательны, декорируя представления с помощью csrf_exempt, когда в этом нет явной необходимости.
Внедрение SQL — это тип атаки, когда недобросовестный пользователь имеет возможность выполнить в базе данных определённый SQL запрос. Результатом выполнения такого запроса может быть удаление или даже утечка данных.
При использовании Django ORM созданный SQL запрос будет правильно экранирован соответствующим драйвером базы данных. Однако, Django предоставляет разработчикам возможность писать запросы напрямую или выполнять собственные запросы. Эти возможности следует использовать умеренно и всегда обращать пристальное внимание на экранирование всех параметров, которые предоставлены пользователем. Такое следует проявлять осторожность при использовании extra().
Clickjacking is a type of attack where a malicious site wraps another site in a frame. This attack can result in an unsuspecting user being tricked into performing unintended actions on the target site.
Django предоставляет защиту от этой атаки в виде модуля X-Frame-Options, который, при использовании соответствующего браузера, может предотвратить отображение сайта внутри фрейма. Есть возможность отключить данную защиту для выбранных представлений или настроить значение отправляемого заголовка.
Этот функциональный слой настоятельно рекомендуется использовать на любом сайте, страницы которого не должны отображаться внутри другого сайта. Можно позволить такое отображение для простых страниц.
Применение этой защиты хорошо отражается на безопасности, хотя и не всегда уместно с практической точки зрения. При отсутствии HTTPS злоумышленник имеет возможность перехватывать аутентификационные данные или любую другую информацию, передаваемую между клиентом и сервером. А в случае активной атаки — может даже изменять данные, передаваемые в любом направлении.
Если вам нужна защита, предоставляемая HTTPS, и на сервере произведена соответствующая настройка ПО, то надо выполнить ещё несколько шагов, чтобы быть уверенным в защите своей информации:
Настройте перенаправление HTTP запросов на HTTPS.
Это можно сделать с помощью функционального слоя Django. Тем не менее, проблема проявляется когда приложение работает за обратным прокси. Часто, обратный прокси настроен на установку заголовка X-Forwarded-SSL (или аналогичного), если входящее соединение шло через HTTPS. Отсутствие такого заголовка может использоваться для определения того, что запрос пришёл через HTTP. Однако, не следует доверять этому заголовку, так как клиент или злоумышленник могут установить этот заголовок самостоятельно.
Таким образом, для обратного прокси рекомендуется настроить перенаправление на HTTPS на главном веб сервере или перенаправление HTTP запросов на приложение, которое будет безусловно отправлять их на HTTPS.
Использование ‘безопасных’ куки.
Если браузер изначально подключается через HTTP, что характерно для большинства браузеров, есть возможность утечки существующих кук. По этой причине вам сделать установить параметры SESSION_COOKIE_SECURE и CSRF_COOKIE_SECURE в True. Это заставить браузер отправлять такие куки только через HTTPS. Следует отметить, это сделает невозможным работу сессий через HTTP, а CSRF защита не будет принимать POST данные, полученные через HTTP (это решается с помощью перенаправления HTTP трафика через HTTPS).
Django использует заголовок Host, предоставляемый клиентом, для создания URL в определённых случаях. Несмотря на то, что эти данные безопасны с точки зрения Cross Site Scripting атак, они могут быть использованы атак CSRF и кэша при определённых условиях. Мы рекомендуем удостовериться, что ваш веб сервер настроен следующим образом:
Он всегда проверяет присылаемые заголовки Host относительно ожидаемого имени хоста.
Не позволяет запросы без установленного заголовка Host.
Не настроено перенаправление всех запросов к виртуальным хостам на приложение Django.
Дополнительно, начиная с 1.3.1, Django требует явную активацию поддержки заголовка X-Forwarded-Host, если ваша конфигурация в нём нуждается.
Несмотря на то, что Django предоставляет защиту прямо из коробки, правильная установка вашего приложения всё ещё имеет значение. Также важно иметь правильно настроенный веб сервер, операционную систему и другие компоненты.
Код вашего приложения должен находиться вне корня веб сервера. Это не позволит случайно отобразить его в виде текста или выполнить его.
Будьте осторожны с любыми файлами, которые загружены пользователями.
Django не ограничивает количество запросов при аутентификации пользователей. Для того, чтобы защититься от перебора логина/пароля, вы можете поставить дополнительное приложение для Django или модуль для веб сервера, чтобы ограничивать такие запросы.
Если ваш сайт принимает файлы, настоятельно советуем ограничить размер таких загрузок в конфигурации веб сервера для предотвращения атак на отказ сервиса (DOS). В случае Apache это легко можно сделать с помощью директивы LimitRequestBody.
Храните содержимое параметра SECRET_KEY в секрете.
Хорошей идеей будет ограничить доступ к вашей системе кэширования и к базе данных с помощью фаервола.
Mar 30, 2016