Content security policy как отключить опера

Обновлено: 07.07.2024

Content Security Policy (CSP) - это дополнительный уровень безопасности, позволяющий распознавать и устранять определённые типы атак, таких как Cross Site Scripting (XSS (en-US) ) и атаки внедрения данных. Спектр применения этих атак включает, но не ограничивается кражей данных, подменой страниц и распространением зловредного ПО.

CSP разрабатывался с возможностью полной обратной совместимости (за исключением CSP version 2, в которой были намеренно определены некоторые противоречия блокирующие обратную совместимость; с деталями можно ознакомиться здесь, в пункте 1.1). Браузеры, которые не поддерживают CSP, все ещё могут работать с серверами, которые поддерживают CSP, и наоборот: браузеры, в которых поддержка CSP отсутствует, будут её игнорировать, продолжая работу в соответствии со стандартными правилами ограничения домена для загрузки контента. В случае, если сайт не предоставляет CSP-заголовки, браузеры, в свою очередь, будут использовать стандартные правила ограничения домена.

В качестве альтернативы настройке сервера, вы можете сконфигурировать CSP с помощью элемента <meta> . Например, так: <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Угрозы

Межсайтовый скриптинг

Основная цель создания CSP заключается в устранении XSS-атак и сборе данных об их попытках. XSS-атаки используют доверие браузера к контенту, полученному с сервера. Зловредные скрипты исполняются в браузере жертвы, поскольку браузер доверяет источнику, даже когда скрипт поставляется не оттуда, откуда кажется.

CSP даёт возможность администраторам серверов снизить или полностью устранить вектора, по которым злоумышленники могут провести XSS, с помощью определения доменов, которые браузер клиента должен считать доверенными источниками исполняемых скриптов. В таком случае, браузер, совместимый с CSP, будет исполнять только те скрипты, которые были получены из списка разрешённых источников, и игнорировать прочие (в т.ч. встраиваемые скрипты и обработчики событий, указанные непосредственно в HTML-атрибутах).

В качестве крайней меры защиты, сайты, которые хотят запретить исполнение скриптов, могут настроить это поведение глобально, с помощью соответствующей опции.

Пакетный сниффинг

Использование CSP

Определение политики

Где policy - это строка, содержащая директивы, описывающие вашу Content Security Policy.

Создание политики

Политика описывается с помощью специальных директив, каждая из которых отвечает за отдельный вид ресурсов или policy area. Политика обязательно должна содержать директиву default-src (en-US), которая будет использоваться для тех ресурсов, для которых не будет описано отдельных правил (полный список вы можете найти в описании директивы default-src (en-US)). Для того чтобы предотвратить исполнение встраиваемых скриптов и заблокировать использование eval() , необходимо определить директиву default-src (en-US) или script-src (en-US). Также использование директивы default-src (en-US) или style-src (en-US) позволит ограничить использование встраиваемых стилей как в style -атрибутах, так и в тэгах <style> .

Примеры: Распространённые случаи применения

В данном разделе приводятся наиболее распространённые сценарии использования CSP.

Пример 1

Вы хотите ограничить источники контента только исходным сервером (исключая поддомены)

Пример 2

Вы хотите разрешить получение контента с доверенного домена и всех его поддоменов (доверенный домен не обязательно должен совпадать с тем, на котором настраиваются CSP.)

Пример 3

Вы хотите разрешить пользователям приложения вставлять в создаваемый ими контент картинки из любого источника, но при этом ограничить источники аудио- и видео-файлов списком доверенных провайдеров. Получение скриптов должно происходить только с конкретного сервера, содержащего доверенный код.

При такой настройке, весь контент доступен для получения только с исходного домена, со следующими исключениями:

Пример 4

Вы хотите удостовериться, что весь получаемый контент для онлайн-банкинга идёт по SSL и атакующий не сможет обрабатывать запросы:

Пример 5

Для просмотра писем в почтовом клиенте вы хотите разрешить использование HTML внутри письма, а также позволить загрузку изображений из любых источников, но запретить использование любого JavaScript-кода и прочий потенциально опасный контент.

Заметьте, что в настройке политики отсутствует директива script-src (en-US); при такой настройке CSP при загрузке скриптов будут использоваться настройки, определяемые директивой default-src (en-US), следовательно все скрипты могут быть загружены только с исходного домена.

Тестирование настройки политики

Для облегчения развёртывания можно настроить развёртывание CSP в режиме report-only. Таким образом, политика не будет ограничивать загрузку, но будет сообщать обо всех нарушениях на указанный в заголовке URI. Кроме того, заголовок report-only может использоваться для тестирования новой политики без полноценного развёртывания.

Для определения вашей политики вы можете использовать заголовок Content-Security-Policy-Report-Only (en-US) следующим образом:

В случае, если оба заголовка (Content-Security-Policy-Report-Only (en-US) и Content-Security-Policy (en-US)) были определены одновременно в одном ответе сервера, обе политики будут обработаны. Политики, описанные в заголовке Content-Security-Policy будут применены, в то время как политики, описанные в заголовке Content-Security-Policy-Report-Only , создадут отчёты, но применены не будут.

Настройка отправки отчётов

По умолчанию, отправка отчётов не производится. Для того чтобы включить отправку отчётов, необходимо в вашей политике определить директиву report-uri (en-US) и указать как минимум один URI, куда будут направляться отчёты:

Кроме того, необходимо настроить свой сервер на получение этих отчётов; вы можете хранить и обрабатывать эти отчёты как считаете нужным.

Синтаксис отчёта о происшествиях

Объект отчёта в формате JSON содержит следующие поля:

Пример отчёта о происшествии

HTML-код страницы signup.html выглядит следующим образом:

Совместимость с браузерами

BCD tables only load in the browser

Для некоторых версий Safari существует специфическая несовместимость реализации CSP. Если установить заголовок Content Security Policy без заголовка Same Origin, то браузер начнёт блокировать и создавать ложно-положительные отчёты о нарушении политики для всего контента, как с запрашиваемого источника, так и из внешних источников.

Content Security Policy

На момент написания статьи стандарт CSP находится в статусе Candidate Recommendation, что означает возможное принятие этого стандарта в будущем W3C консорциумом. На данный момент все популярные браузеры поддерживают этот стандарт.

Поддержка Content Security Policy в различных браузерах
Браузер Версия Примечания
Chrome 25+ Полная поддержка
Firefox 23+
Opera 15+
Яндекс.Браузер
Firefox 4-22 Поддерживают нестандартный заголовок X-Content-Security-Policy и частично поддерживают стандартный
IE 10+
Chrome 14-24+ Поддерживают нестандартный заголовок X-Webkit-CSP и частично поддерживают стандартный
Safari 5-7

Как отсутствие CSP может навредить сайту?

Содержание Content Security Policy

Сейчас ещё немного теории, и потом сразу перейдём к практики, потерпите 😉

Устанавливаем Content Security Policy на сайт

Content Security Policy в консоли Google Chrome

Чтобы лучше понять как работает Content Security Policy, давайте немного поэкспериментируем. Создайте файл index.php и напишите в него следующий код:

Теперь давайте изменим заголовок с Content-Security-Policy-Report-Only на Content-Security-Policy и посмотрим что будет:

Пендальф CSP никого не пустил.

Инлайн скрипт не был выполнен, а картинка не загрузилась. Круто, правда?

Обработка отчётов

С этим отчётом вы можете делать всё что угодно, например сохранять в базу, отправлять на почту. Я предлагаю записывать все нарушения в csv файл. Давайте сделаем это!

Создайте файл collector.php и напишите в него следующие строки:

Полезные материалы по Content Security Policy

Борис Заболотских

Автор блога Борис Заболотских

Здравствуй дорогой читатель! Я рад приветствовать тебя на страницах моего блога. Уже несколько лет я занимаюсь веб-программированием и рад поделиться с тобой своими знаниями и советами. Если тебе понравились мои статьи, ты можешь подписаться на рассылку блога, из неё ты узнаешь много интересного!

Content Security Policy

Эта информация не нужна обычным пользователям компьютера, но будет полезна для людей, занимающихся разработкой и администрированием сайтов. Как известно страницы сайта состоят из различных ресурсов, таких как скрипты, таблицы стилей, изображения, шрифты и так далее. Они могут загружаться как непосредственно с сервера, где расположен сам сайт, так и с любого другого домена в интернете. Это имеет свои преимущества и недостатки.

Серьезным минусом загрузки ресурсов из другого источника является потенциальная уязвимость внедрения вредоносного контента. Например, в виде межсайтовых скриптовых атак или на английском Cross Site Scripting (XSS) и внедрения зловредных данных. Браузер, загружая страницу доверяет всему контенту, который на ней присутствует, даже если это зловредный код, внедренный незаконно.

Он просто не может отличить один от другого. Как защитить сайт от атак злоумышленников с использованием XSS посвящена данная статья. Для решения подобного рода проблем и повышения безопасности веб-приложений был разработан специальный защитный механизм, подсказывающий браузеру какой контент является незаконным на данной странице.

Другими словами, сервер только информирует о перечне доверенных источников и типах ресурсов на данной странице, а исполнение данных рекомендаций лежит полностью на клиентском ПО. Поэтому требуется поддержка данной технологии в браузере, с чем как всегда все не совсем гладко.

В случае обнаружения нарушения безопасности на странице, данный ресурс блокируется и в консоли браузера появляется соответствующее предупреждение на подобии «Refused to load the script . » с перечнем запрещенных к загрузке ресурсов и причинами блокировки.

Правила формирования заголовка

Что такое Content Security Policy мы выяснили, способы добавления на сайт мы рассмотрим позже, а сейчас займемся самим заголовком. Главное правило, которое нужно запомнить. Запрещено все, что не разрешено в директиве в явном виде.

Заголовок должен соответствовать следующему формату. Название заголовка отделяется двоеточием, значения директив (directive) пишутся через пробел, директивы отделяются друг от друга точкой с запятой. Наследование не применяется, каждая директива должна содержать свой «белый список» разрешенных значений.

Имеются специальные ключевые слова, которые записываются в одинарных кавычках.

Директивы Content Security Policy

CSP предоставляет широкий набор директив для разных случаев использования и они являются регистронезависимыми.

default-src — устанавливает значение по умолчанию для других директив, если они не заданы в явном виде. Рассмотрим несколько примеров.

Любые внешние ресурсы могут загружаться только с текущего домена, но запрещены встроенные, динамические, data: и остальные.

Любые ресурсы могут загружаться из любых источников. Не распространяется на встроенные и динамически добавляемые ресурсы.

Дополнительно разрешает инлайн и динамически подключаемые ресурсы.

Устанавливает для всех директив значение по умолчанию «нет», в результате все ресурсы страницы окажутся заблокированными и загрузится только html документ. Рекомендуется использовать, чтобы затем прописать правила только для тех ресурсов, которые реально используются на сайте.

script-src — задает разрешенный список источников контента для внешних скриптов JavaScript и других сценариев наподобие таблиц стилей XSLT.

Данные правила действуют только на подключение внешних ресурсов. Чтобы разрешить динамическое добавление скриптов используется слово 'unsafe-eval' .

Аналогично для разрешения запуска встроенных ресурсов используется ключевое слово 'unsafe-inline' . Проблема при этом в том, что сильно снижается уровень безопасности. Поэтому для более точного контроля за инлайн ресурсами существует ключевое слово 'nonce-$random' , где $random это случайная одноразовая строка.

Смысл в том, что сервер каждый раз при запросе страницы генерирует ее заново и подставляет в заголовок Content-Security-Policy, одновременно добавляя в качестве значения атрибута nonce в тег скрипта. Это можно использовать как с внешними, так и со встроенными скриптами.

Альтернативным вариантом для встроенных сценариев является использование их хэша. Он обеспечивает большую надежность, однако сильнее нагружает браузер. Для этого вычисляется хэш кода, расположенного между тегами <scrypt> по алгоритму SHA-256, SHA-384 или SHA-512 и затем кодируется с помощью base64. Получившейся результат добавляется в заголовок с указанием использованного алгоритма хеширования. Так для сценария alert('Привет мир!'); это выглядит так.

Браузер вычисляет хэш встроенного сценария на странице и если он совпадает со значением из заголовка, то сценарий выполняется. Стоит помнить, что для хэша имеют значение любые символы, в том числе и пробелы. Поэтому исполнится только первый из следующих вариантов, несмотря на то что сам код идентичен.

style-src — белый список разрешенные источников для каскадных таблиц стилей документа. Здесь все тоже самое, что и в script-src .

font-src — регламентирует разрешенные источники загрузки шрифтов. Например, если в директиве default-src задан собственный домен, а ваш сайт загружает веб-шрифты с сервиса google, то необходимо явно разрешить загрузку из внешнего источника.

child-src — используется для контроля за фреймами, заменило устаревший frame-src .

base-uri — ограничивает URL которые могут использоваться для указания базового адреса в теге <base> документа.

form-action — регламентирует адреса, на которые могут быть отправлены формы на странице.

img-src — список разрешенных источников для загрузки изображений. Изображения, встраиваемые в страницу с помощью data, нужно разрешать отдельно.

Допустимы изображения только с собственного домена, остальное с любого адреса по защищенному протоколу.

Запрещены любые изображения в том числе со своего хоста, но разрешены подключенные через data

media-src — регулирует источники аудио, видео и связанных текстовых данных.

object-src — указывает возможные источники для загрузки плагинов на страницу.

plugin-types — регулирует разрешенный тип встраиваемых плагинов на основе их MIME типа. Например, разрешает только использование Flash.

report-uri — каждая попытка загрузки ресурса из неразрешенного источника или запрещенного типа считается нарушением политики безопасности контента. В этой директиве указывается URL адрес, по которому браузер пользователя будет отсылать POST запрос в формате JSON о такой ситуации. Не работает, в случае добавления заголовка с помощью тега meta .

sandbox — помещает страницу в песочницу и определяет разрешенные действия, используются такие же флаги как и для iframe.

Мы рассмотрели возможности имеющиеся в CSP Level 2 по защите сайта от Cross Site Scripting и подмены контента. Несмотря на очевидные преимущества он не используется в интернете на сегодняшний день достаточно широко. Этому есть простое объяснение. Для его внедрения нужно приложить много усилий и зачастую переписать часть кода для обеспечения надлежащего уровня защиты.

Все относительно просто, когда для загрузки ресурсов используется только собственный домен или несколько заранее известных сторонних адресов. Среднестатистический сайт в интернете использует счетчики посещаемости, различные рекламные сети и виджеты. Все это тянет за собой шлейф из десятков дополнительно загружаемых на страницу ресурсов с самых разных URL зачастую неизвестных заранее.

В этой ситуации настройка становится совсем не тривиальной задачей. Однако даже в этом случае, политика безопасности контента может найти свое применение, например для защиты административной части сайта, страницы оплаты или других важных разделов. Это поможет создать дополнительный барьер от кражи сессий, паролей и другой конфиденциальной информации.

Стоит иметь в виду, что антивирусы могут вмешиваться в работу сайта. Например, Касперский встраивает в страницу собственный скрипт для ее проверки, поэтому когда он обнаруживает в ответе сервера этот заголовок, то он его модернизирует на лету и добавляет правила разрешающие ему выполняться на странице, чтобы браузер его не заблокировал.

Заголовок Content-Security-Policy-Report-Only

Данный заголовок аналогичен предыдущему, с той лишь разницей, что он не блокирует загрузку ресурсов, а только информирует о факте нарушения политики безопасности контента.

Как добавить HTML-заголовок на страницу

Сервер Nginx, конфигурационный файл nginx.conf

HTML метатег meta добавляется в head страницы. Данный тег не действует на ресурсы, расположенные на странице перед ним. Не может использоваться для Content-Security-Policy-Report-Only

Что делать, если вы не добавляли данный заголовок, но получаете ошибки в консоли связанные с CSP. Значит он добавляется автоматически сервером, CMS или плагином. Нужно найти источник его появления и отключить его вывод или настроить нужным вам образом. Если такой возможно нет, то можно попробовать его переопределить, добавив собственный с нужными настройками.

Применение CSP при грамотной настройке позволяет существенно повысить безопасность и снизить риск межсайтового скриптинга. Правда для этого нужно отказаться от использования unsafe-unline и unsafe-eval , что бывает не просто.


Типичный пример использования CSP — это разрешение загрузки ресурсов с собственного домена (self) и разрешение выполнения инлайн-сценариев:

Такая политика подразумевает «запрещено все, что не разрешено». В данной конфигурации будет запрещено любое использование функций, выполняющих код в виде строки, таких как eval , setTimeout , setInterval , так как отсутствует настройка 'unsafe-eval' .



Запрещено грузить любой контент с внешних источников, в том числе изображения, CSS, WebSocket. И конечно же, JS.

Для примера я специально оставил XSS в этом месте, задача — украсть секрет пользователя.

Но не стоит забывать, что self позволяет работать в контексте SOP в рамках этого домена, поэтому мы по-прежнему можем грузить сценарии, создавать фреймы, изображения. Если вспомнить о фреймах, то CSP распространяется и на фреймы, в том числе если в качестве протокола будет указан data, blob или будет сформирован фрейм с помощью атрибута srcdoc.



WARNING

Статья написана в исследовательских целях. Вся информация в ней носит ознакомительный характер. Ни автор, ни редакция не несет ответственности за неправомерное использование упомянутых в ней аппаратных платформ, программ и техник!

Можно ли выполнить JS в текстовом файле?

Для начала вспомним один трюк. Если современный браузер открывает изображение или какой-то текстовый файл, он автоматически преобразуется в HTML-страницу.



Это нужно для корректного отображения содержимого пользователю, чтобы у изображения был фон и она была расположена по центру. Но iframe также является окном! Поэтому открытые в нем файлы, которые отображаются в браузере, например favicon.ico или robots.txt, автоматически преобразуются в HTML, независимо от того, корректные ли в нем данные, главное — чтобы был правильный content-type .

Но что, если фрейм будет содержать страницу сайта, но уже без заголовка CSP? Вопрос риторический. Выполнит ли открытый фрейм без политики все JS, которые будут у него внутри? Если иметь XSS на странице, мы можем сами записать свой JS внутрь фрейма.

Для теста сформируем сценарий, который открывает iframe. Для примера возьмем bootstrap.min.css, путь к которому указан на странице выше.



Теперь посмотрим на содержимое фрейма. Отлично! CSS был преобразован в HTML, и нам удалось переписать содержимое head (хотя оно было пустое). Теперь проверим, сработает ли в нем подключение внешнего JavaScript-файла.



Таким образом мы можем выполнить инъекцию через iframe, создать в нем свой JS-сценарий и обратиться в окно-родитель, чтобы украсть оттуда данные.

Для полноценной эксплуатации XSS достаточно открыть фрейм с любым путем, где отсутствует политика безопасности. Это могут быть стандартные favicon.ico, robots.txt, sitemap.xml, CSS/JS-файлы, загруженные пользователями изображения и прочее.

PoC проведения атаки через robots.txt .

Ошибки сервера для обхода CSP

Но что, если любой корректный ответ (200 — OK) содержит X-Frame-Options: Deny? Вторая ошибка, которую допускают при внедрении CSP, — это отсутствие защитных заголовков при ошибках веб-сервера. Самый простой вариант — обратиться на несуществующую страницу. Я заметил, что многие ресурсы ставят X-Frame-Options только на ответы 200, но 404 игнорируют.

Чтобы гарантированно вызвать 400 bad request на примере nginx, достаточно обратиться на директорию выше с помощью конструкции /%2e%2e%2f . Чтобы препятствовать нормализации ссылки браузером (браузер уберет /../ и отправит / ), делаем urlencode точки и последнего слеша:



Другой из вариантов развития событий — передача некорректного urlencode в пути, например /% или /%%z .

Однако самый простой способ получить ошибку веб-сервера — это превышение длины URL. Современные браузеры могут сформировать ссылку много больше, чем поддерживает веб-сервер. А у веб-серверов по умолчанию размер ссылки не должен превышать 8 Кбайт данных, как в nginx, так и в Apache.

Для этого вызываем похожий сценарий, например с длиной пути в 20 000 байт:



Если вспомнить о других лимитах — это длина кук. Количество и длина кук в браузере может быть больше, чем поддерживают веб-серверы. По аналогии:

Создаем огромные cookie:

Открываем фрейм на любой адрес, сервер вернет ошибку (и часто без XFO и CSP).

Удаляем огромные cookie:

Почему это работает?

Потому что политика подключаемого ресурса в фрейме контролируется самим ресурсом.

На сайте Useless CSP ты найдешь множество примеров сайтов, на которых неверно настроена CSP, что сводит всю защиту на нет.

Как этого избежать

Заголовок Content-Security-Policy должен присутствовать на всех страницах, даже на ошибках веб-сервера.

Настройка CSP должна происходить таким образом, чтобы права были минимально необходимыми для корректной работы ресурса, если это возможно. Попробуй включить Content-Security-Policy-Report-Only: default-src 'none' и постепенно включать правила для тех или иных ситуаций.

Если для корректной работы ресурса необходимо использовать unsafe-inline , обязательно нужно внедрить nonce или hash-source, без этого защита от атак типа XSS сходит на нет. А если CSP не защищает от атак, какой в нем смысл?

Дополнительно, как рассказал @majorisc, данные со страницы можно увести с помощью RTCPeerConnection , передавая секрет через DNS-запросы. Default-src 'self' , к сожалению, не защищает и от этого.

Bo0oM

Security researcher, whitehat, bug bounty practicant, blogger, noob, script kiddie.

Читайте также: