CSP
Политика безопасности контента (CSP)
Политика безопасности контента (CSP) — дополнительный уровень безопасности, помогающий обнаруживать и смягчать определенные типы атак, включая межсайтовый скриптинг (XSS) и атаки с инъекцией данных. Эти атаки используются для всего, от кражи данных до вандализма сайтов и распространения вредоносных программ.
CSP разработана с полной обратной совместимостью (за исключением версии CSP 2, где есть некоторые явно указанные несовместимости; больше деталей здесь в разделе 1.1). Браузеры, которые не поддерживают её, всё ещё работают с серверами, которые её реализуют, и наоборот: браузеры, которые не поддерживают CSP, игнорируют её, работая как обычно, по умолчанию используя стандартную политику одного происхождения для веб-контента. Если сайт не предоставляет заголовок CSP, браузеры аналогичным образом используют стандартную политику одного происхождения.
Для включения CSP вам необходимо настроить веб-сервер на возвращение заголовка Content-Security-Policy HTTP. (Иногда можно встретить упоминания заголовка X-Content-Security-Policy, но это более старая версия, и вам больше не нужно его указывать.)
В качестве альтернативы, для настройки политики можно использовать элемент <meta>, например:
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src https://*; child-src 'none';" />
Угрозы
Смягчение межсайтовых атак со скриптированием
Основная цель CSP — смягчить и отслеживать атаки XSS. Атаки XSS используют доверие браузера к содержимому, полученному от сервера. Вредоносные скрипты выполняются браузером жертвы, потому что браузер доверяет источнику содержимого, даже если оно не поступает от предполагаемого источника.
CSP позволяет администраторам серверов уменьшить или устранить векторы, посредством которых может произойти XSS, указав домены, которые браузер должен рассматривать как допустимые источники исполняемых скриптов. Совместимый с CSP браузер будет затем выполнять только скрипты, загруженные из файлов-источников, полученные от разрешенных доменов, игнорируя все другие скрипты (включая встроенные скрипты и атрибуты обработки событий HTML).
В качестве крайней меры защиты сайты, которые не хотят, чтобы скрипты выполнялись вообще, могут запретить выполнение скриптов глобально.
Смягчение атак перехвата пакетов
Помимо ограничения доменов, из которых может загружаться контент, сервер может указать, какие протоколы разрешены; например (и, желательно, с точки зрения безопасности), сервер может указать, что весь контент должен загружаться с использованием HTTPS. Полная стратегия обеспечения безопасности передачи данных включает не только применение HTTPS для передачи данных, но также и маркировку всех куки с атрибутом secure и предоставление автоматических редиректов с HTTP-страниц на их HTTPS-аналоги. Сайты также могут использовать заголовок HTTP Strict-Transport-Security, чтобы гарантировать, что браузеры подключаются к ним только по защищённому каналу.
Использование CSP
Настройка политики безопасности контента включает добавление заголовка HTTP Content-Security-Policy к веб-странице и присвоение значений для управления тем, какие ресурсы пользовательский агент разрешено загружать для этой страницы. Например, страница, которая загружает и отображает изображения, может разрешить загрузку изображений откуда угодно, но ограничить действие формы определённым конечным пунктом. Правильно разработанная политика безопасности контента помогает защитить страницу от межсайтовой атаки со скриптированием. Эта статья объясняет, как правильно создавать такие заголовки и предоставляет примеры.
Указание вашей политики
Вы можете использовать заголовок HTTP Content-Security-Policy для указания своей политики, например так:
Content-Security-Policy: policy
Политика представляет собой строку, содержащую директивы политики, описывающие вашу политику безопасности контента.
Создание политики
Политика описывается с помощью набора директив политики, каждая из которых описывает политику для определённого типа ресурсов или области политики. Ваша политика должна включать директиву политики default-src, которая является резервной для других типов ресурсов, когда у них нет собственных политик (полный список см. в описании директивы default-src). Политика должна включать директиву default-src или script-src для предотвращения выполнения встроенных скриптов, а также блокирования использования eval(). Политика должна включать директиву default-src или style-src для ограничения применения встроенных стилей из элемента <style> или атрибута style. Существуют определённые директивы для широкого спектра типов элементов, чтобы каждый тип мог иметь свою политику, включая шрифты, фреймы, изображения, аудио- и видео-медиа, скрипты и рабочие процессы.
Полный список директив политики см. на странице справки для заголовка Content-Security-Policy.
Примеры: Общие варианты использования
В этом разделе приведены примеры некоторых распространённых сценариев политики безопасности.
Пример 1
Администратор веб-сайта хочет, чтобы весь контент поступал от собственного происхождения сайта (это исключает дочерние домены).
Content-Security-Policy: default-src 'self'
Пример 2
Администратор веб-сайта хочет разрешить контент из доверенного домена и всех его дочерних доменов (при этом не обязательно, чтобы это был тот же домен, что и CSP).
Content-Security-Policy: default-src 'self' example.com *.example.com
Пример 3
Администратор веб-сайта хочет разрешить пользователям веб-приложения включать изображения из любого источника в свой собственный контент, но ограничить аудио- или видео-медиа доверенными поставщиками, а все скрипты только определённому серверу, который хранит доверенный код.
Content-Security-Policy: default-src 'self'; img-src *; media-src example.org example.net; script-src userscripts.example.com
Здесь по умолчанию контент разрешён только из происхождения документа, с указанными исключениями:
- Изображения могут загружаться откуда угодно (обратите внимание на символ «*» — универсальный символ).
- Медиа разрешено только из example.org и example.net (и не из дочерних сайтов этих доменов).
- Исполняемые скрипты разрешены только из userscripts.example.com.
Пример 4
Администратор веб-сайта онлайн-банка хочет убедиться, что весь его контент загружается с использованием TLS, чтобы предотвратить перехват запросов злоумышленниками.
Content-Security-Policy: default-src https://onlinebanking.example.com
Сервер разрешает доступ только к документам, загружаемым именно по HTTPS через единственный источник onlinebanking.example.com.
Пример 5
Администратор веб-сайта веб-почты хочет разрешить HTML в письмах, а также изображения, загружаемые откуда угодно, но не JavaScript или другой потенциально опасный контент.
Content-Security-Policy: default-src 'self' *.example.com; img-src *
Обратите внимание, что в этом примере не указана директива script-src; с примерной CSP на этом сайте используется настройка, указанная в директиве default-src, что означает, что скрипты могут загружаться только с исходного сервера.
Тестирование вашей политики
Для упрощения развертывания CSP может быть развернута в режиме отслеживания нарушений. Политика не применяется, но любые нарушения сообщаются в предоставленный URI. Кроме того, заголовок только для отслеживания нарушений можно использовать для тестирования будущей версии политики без её фактического развертывания.
Вы можете использовать заголовок HTTP Content-Security-Policy-Report-Only для указания своей политики, например так:
Content-Security-Policy-Report-Only: policy
Если и заголовок Content-Security-Policy-Report-Only, и заголовок Content-Security-Policy присутствуют в одном ответе, обе политики соблюдаются. Политика, указанная в заголовках Content-Security-Policy, применяется, в то время как политика Content-Security-Policy-Report-Only генерирует отчёты, но не применяется.
Включение отчётов
По умолчанию отчёты о нарушениях не отправляются. Для включения отчётов о нарушениях необходимо указать директиву политики report-uri, указав по крайней мере один URI, куда нужно доставлять отчёты:
Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi
Затем необходимо настроить сервер на получение отчётов; он может хранить или обрабатывать их любым способом, который вы сочтёте уместным.
Синтаксис отчета о нарушении
Объект отчета JSON содержит следующие данные:
blocked-uri-
URI ресурса, загрузка которого была заблокирована политикой Content Security Policy. Если заблокированный URI имеет другой источник, чем
document-uri, то заблокированный URI усекается, содержа в себе только схему, хост и порт. disposition-
Либо
"enforce", либо"report", в зависимости от того, используется заголовокContent-Security-Policy-Report-Onlyили заголовокContent-Security-Policy. document-uri-
URI документа, в котором произошло нарушение.
effective-directive-
Директива, применение которой привело к нарушению. Некоторые браузеры могут предоставлять разные значения, например, Chrome может предоставлять
style-src-elem/style-src-attr, даже если фактически применялась директиваstyle-src. original-policy-
Исходная политика, указанная в заголовке
Content-Security-PolicyHTTP. -
referrerУстаревшее Нестандартное -
Ссылка (referrer) документа, в котором произошло нарушение.
script-sample-
Первые 40 символов встроенного скрипта, обработчика событий или стиля, которые привели к нарушению. Применимо только к нарушениям
script-src*иstyle-src*, когда они содержат'report-sample' status-code-
HTTP код состояния ресурса, на котором был создан глобальный объект.
violated-directive-
Название раздела политики, который был нарушен.
Пример отчета о нарушении
Рассмотрим страницу по адресу http://example.com/signup.html. Она использует следующую политику, запрещающую всё, кроме стилей из cdn.example.com.
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
HTML страницы signup.html выглядит так:
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8" /> <title>Sign Up</title> <link rel="stylesheet" href="css/style.css" /> </head> <body> Here be content. </body> </html>
Вы видите ошибку? Стилей разрешено загружать только из cdn.example.com, но сайт пытается загрузить стиль из собственного источника (http://example.com). Браузер, способный применять CSP, отправит следующий отчет о нарушении как POST-запрос на http://example.com/_/csp-reports, когда страница будет посещена:
{ "csp-report": { "document-uri": "http://example.com/signup.html", "referrer": "", "blocked-uri": "http://example.com/css/style.css", "violated-directive": "style-src cdn.example.com", "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports" } }
Как видите, отчет включает полный путь к нарушающему ресурсу в blocked-uri. Это не всегда так. Например, если signup.html пытался загрузить CSS из http://anothercdn.example.com/stylesheet.css, браузер не включит полный путь, а только источник (http://anothercdn.example.com). Спецификация CSP объясняет это странное поведение. В кратком изложении, это делается для предотвращения утечки конфиденциальной информации о ресурсах других источников.
Совместимость с браузерами
| Рабочие столы | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | |
CSP |
25
14
|
14 |
23
4
|
10
Only supporting 'sandbox' directive.
|
15 |
7
6
|
Да |
Да |
23 |
Да |
7
6
|
Да |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
base-uri |
40 |
79 |
35 |
Нет |
27 |
10 |
Да |
Да |
35 |
Да |
9.3 |
Да |
block-all-mixed-content |
Да |
≤79 |
48 |
Нет |
Да |
Нет |
Да |
Да |
48 |
Да |
Нет |
Да |
child-src |
40 |
15 |
45 |
Нет |
27 |
10 |
Да |
Да |
45 |
Да |
9.3 |
Да |
connect-src |
25 |
14 |
23
Before Firefox 50, ping attributes of <a> elements weren't covered by connect-src.
|
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
default-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
font-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
form-action |
40 |
15 |
36 |
Нет |
27 |
10 |
Да |
Да |
36 |
Да |
9.3 |
Да |
frame-ancestors |
40 |
15 |
33
Before Firefox 58,
frame-ancestors is ignored in Content-Security-Policy-Report-Only. |
Нет |
26 |
10 |
Да |
Да |
33
Before Firefox for Android 58,
frame-ancestors is ignored in Content-Security-Policy-Report-Only. |
Да |
9.3 |
Да |
frame-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
img-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
manifest-src |
Да |
79 |
41 |
Нет |
Да |
Нет |
Да |
Да |
41 |
Да |
Нет |
Да |
media-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
meta-element-support |
Да |
≤18 |
45 |
Нет |
Да |
Да |
Да |
Да |
45 |
Да |
Да |
Да |
object-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
plugin-types |
40-90 |
15-90 |
Нет |
Нет |
27-76 |
10 |
Да-90 |
Да-90 |
Нет |
Да-64 |
9.3 |
Да-15.0 |
prefetch-src |
Нет
See bug 801561.
|
Нет
See bug 801561.
|
Нет
See bug 1457204.
|
Нет |
Нет
See bug 801561.
|
Нет
See bug 185070.
|
Нет
See bug 801561.
|
Нет
See bug 801561.
|
Нет
See bug 1457204.
|
Нет
See bug 801561.
|
Нет
See bug 185070.
|
Нет
See bug 801561.
|
referrer |
33-56 |
Нет |
37-62 |
Нет |
20-43 |
Нет |
4.4.3-56 |
33-56 |
37-62 |
20-43 |
Нет |
2.0-6.0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
report-sample |
59 |
≤79 |
Нет |
Нет |
46 |
15.4 |
59 |
59 |
Нет |
43 |
15.4 |
7.0 |
report-to |
70 |
79 |
Нет |
Нет |
57 |
Нет |
70 |
70 |
Нет |
49 |
Нет |
10.0 |
report-uri |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
require-sri-for |
54 |
79 |
Нет |
Нет |
41 |
Нет |
54 |
54 |
Нет |
41 |
Нет |
6.0 |
require-trusted-types-for |
83 |
83 |
Нет |
Нет |
69 |
Нет |
83 |
83 |
Нет |
59 |
Нет |
13.0 |
sandbox |
25 |
14 |
50 |
10 |
15 |
7 |
Да |
Да |
50 |
Да |
7 |
Да |
script-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
script-src-attr |
75 |
79 |
105
предварительный просмотр
|
Нет |
62 |
Нет |
75 |
75 |
Нет |
54 |
Нет |
11.0 |
script-src-elem |
75 |
79 |
105
предварительный просмотр
|
Нет |
62 |
Нет |
75 |
75 |
Нет |
54 |
Нет |
11.0 |
strict-dynamic |
52 |
79 |
52 |
Нет |
39 |
15.4 |
52 |
52 |
Нет |
41 |
15.4 |
6.0 |
style-src |
25 |
14 |
23 |
Нет |
15 |
7 |
Да |
Да |
23 |
Да |
7 |
Да |
style-src-attr |
75 |
79 |
105
предварительный просмотр
|
Нет |
62 |
Нет |
75 |
75 |
Нет |
54 |
Нет |
11.0 |
style-src-elem |
75 |
79 |
105
предварительный просмотр
|
Нет |
62 |
Нет |
75 |
75 |
Нет |
54 |
Нет |
11.0 |
trusted-types |
83 |
83 |
Нет |
Нет |
69 |
Нет |
83 |
83 |
Нет |
Нет |
Нет |
13.0 |
unsafe-hashes |
69 |
79 |
Нет
См. ошибку 1343950.
|
Нет |
56 |
15.4 |
69 |
69 |
Нет
См. ошибку 1343950.
|
48 |
15.4 |
10.0 |
upgrade-insecure-requests |
43 |
17 |
42 |
Нет |
30 |
10.1 |
43 |
43 |
42 |
30 |
10.3 |
4.0 |
worker-src |
59
Chrome 59 и выше пропускает устаревшую директиву
child-src. |
79 |
58 |
Нет |
46
Opera 46 и выше пропускает устаревшую директиву
child-src. |
15.5 |
59
Chrome 59 и выше пропускает устаревшую директиву
child-src. |
59
Chrome 59 и выше пропускает устаревшую директиву
child-src. |
58 |
43
Opera 43 и выше пропускает устаревшую директиву
child-src. |
15.5 |
7.0 |
worker_support |
Да |
≤79 |
50 |
Нет |
Да |
10 |
Да |
Да |
50 |
Да |
10 |
Да |
|---|
Примечания по совместимости
Существует определенная несовместимость в некоторых версиях веб-браузера Safari, при которой, если заголовок Content Security Policy установлен, но заголовок Same Origin нет, браузер заблокирует контент, размещенный на собственном сервере, и сторонний контент, и неправильно сообщит, что это связано с тем, что Content Security Policy не разрешает данный контент.
См. также
-
Content-Security-PolicyЗаголовок HTTP -
Content-Security-Policy-Report-OnlyЗаголовок HTTP - Content Security в WebExtensions
- CSP в Web Workers
- Конфиденциальность, разрешения и безопасность информации
- CSP Evaluator - Оцените вашу Content Security Policy
© 2005–2022 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP