Заголовки: CSP.script-src
Content-Security-Policy: директива script-src
Baseline Широко доступно *
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в разных версиях браузеров. Она доступна во всех браузерах с августа 2016 года.
* Некоторые части этой функции могут поддерживаться в разной степени.
Директива HTTP Content-Security-Policy (CSP) script-src указывает допустимые источники JavaScript. Сюда входят не только URL-адреса, загружаемые непосредственно в элементы <script>, но и такие элементы, как встроенные обработчики событий скриптов (onclick) и таблицы стилей XSLT, которые могут запускать выполнение скриптов.
| Версия CSP | 1 |
|---|---|
| Тип директивы | Директива Fetch |
default-src резервная директива | Да. Если эта директива отсутствует, пользовательский агент будет искать директиву default-src. |
Синтаксис
Content-Security-Policy: script-src 'none'; Content-Security-Policy: script-src <source-expression-list>;
Эта директива может иметь одно из следующих значений:
'none'-
Ресурсы этого типа загружать нельзя. Одинарные кавычки обязательны.
<source-expression-list>-
Разделённый пробелами список значений выражений источников. Ресурсы этого типа можно загружать, если они соответствуют любому из указанных выражений источников. Для этой директивы применимы любые значения выражений источников, перечисленные в разделе Синтаксис директивы Fetch.
Примеры
>Внесение ресурсов доверенных доменов в список разрешённых
Пусть этот заголовок CSP разрешает скрипты только с https://example.com:
Content-Security-Policy: script-src https://example.com/
следующий скрипт будет заблокирован, не загрузится и не выполнится:
<script src="https://not-example.com/js/library.js"></script>
Обратите внимание, что встроенные обработчики событий также блокируются:
<button id="btn" onclick="doSomething()">Click me</button>
Их следует заменить вызовами addEventListener:
document.getElementById("btn").addEventListener("click", doSomething);
Если вы не можете заменить встроенные обработчики событий, можно использовать выражение источника 'unsafe-hashes', чтобы разрешить их. Подробнее см. в разделе Небезопасные хеши.
Внесение внешних скриптов в список разрешённых с помощью хешей
Разрешение доверенных доменов, описанное в предыдущем разделе, — это широкий подход к указанию местоположений, из которых можно безопасно загружать код. Это практичное решение, особенно если на вашем сайте используется много ресурсов и вы уверены, что доверенный сайт не будет взломан.
Альтернативный способ — указать разрешённые скрипты с помощью хешей файлов. При таком подходе внешний файл в элементе <script> можно загрузить и выполнить, только если все допустимые значения хеша в его атрибуте integrity совпадают с разрешёнными значениями в заголовке CSP. Функция целостности подресурсов дополнительно проверяет, что загруженный файл имеет указанный хеш и, следовательно, не был изменён. Это безопаснее, чем доверять домену, поскольку файлы будут использоваться, только если они не изменены, даже при загрузке со взломанного сайта. Однако этот способ более детализирован и требует обновления значений хешей в CSP и элементах script при каждом изменении соответствующих скриптов.
Пример заголовка CSP ниже демонстрирует этот подход. Он разрешает скрипты, для которых хеш SHA384 равен oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC или хеш SHA256 равен fictional_value.
Content-Security-Policy: script-src 'sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC' 'sha256-fictional_value'
Следующий скрипт example-framework.js должен загрузиться, поскольку значение хеша в его атрибуте integrity также указано в CSP (при условии, что после загрузки файл действительно имеет этот хеш!).
<script src="https://example.com/example-framework.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
Атрибут integrity может содержать несколько значений, каждое из которых представляет хеш файла, вычисленный с помощью другого алгоритма. Чтобы внешний скрипт загрузился, CSP требует, чтобы все допустимые значения хеша в атрибуте также присутствовали в объявлении CSP script-src. Поэтому следующий скрипт не загрузится: второго хеша нет в приведённом выше заголовке CSP.
<script src="https://example.com/example-framework.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC sha256-not-in-csp" crossorigin="anonymous"></script>
Это правило применяется только к допустимым значениям хеша. Значения, которые браузер не распознаёт как хеши, игнорируются, поэтому следующий скрипт должен загрузиться:
<script src="https://example.com/example-framework.js" integrity="invalid-or-unsupported-hash sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
Дополнительные сведения о вычислении хешей и использовании атрибута integrity приведены в разделе «Целостность подресурсов».
Небезопасные встроенные скрипты
Примечание: Запрет встроенных стилей и скриптов — одно из важнейших преимуществ CSP для безопасности. Если без них никак не обойтись, есть несколько механизмов, позволяющих их использовать. Хеши применяются к встроенным скриптам и стилям, но не к обработчикам событий. Подробнее см. в разделе Небезопасные хеши.
Чтобы разрешить встроенные скрипты и стили, можно указать 'unsafe-inline', источник nonce или источник хеша, соответствующий встроенному блоку. Следующая политика безопасности содержимого разрешит все встроенные элементы <script>:
Content-Security-Policy: script-src 'unsafe-inline';
Следующий элемент <script> будет разрешён этой политикой:
<script> const inline = 1; // … </script>
Разрешение всех встроенных скриптов считается риском для безопасности, поэтому рекомендуется использовать источник nonce или источник хеша. Чтобы разрешить встроенные скрипты и стили с помощью источника nonce, необходимо сгенерировать случайное значение nonce (используя криптографически стойкий генератор случайных токенов) и включить его в политику. Важно учитывать, что это значение nonce нужно генерировать динамически: оно должно быть уникальным для каждого HTTP-запроса.
Content-Security-Policy: script-src 'nonce-2726c7f26c'
Затем необходимо указать тот же nonce в элементе <script>:
<script nonce="2726c7f26c"> const inline = 1; // … </script>
Кроме того, можно создать хеши для встроенных скриптов. CSP поддерживает sha256, sha384 и sha512.
Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='
При создании хеша не включайте теги <script>. Учитывайте, что важны регистр символов и пробелы, в том числе в начале и конце.
<script> const inline = 1; </script>
Небезопасные хеши
Политики для встроенных ресурсов с хешами, например script-src 'sha256-{HASHED_INLINE_SCRIPT}', разрешают скрипты и стили по их хешу, но не обработчики событий:
<!-- Allowed by CSP: script-src 'sha256-{HASHED_INLINE_SCRIPT}' -->
<script>
const inline = 1;
</script>
<!-- CSP: script-src 'sha256-{HASHED_EVENT_HANDLER}'
will not allow this event handler -->
<button onclick="myScript()">Submit</button>
Вместо разрешения 'unsafe-inline' можно использовать выражение источника 'unsafe-hashes', если код нельзя обновить, заменив его эквивалентными вызовами addEventListener. Пусть HTML-страница содержит следующий встроенный обработчик события:
<!-- I want to use addEventListener, but I can't :( --> <button onclick="myScript()">Submit</button>
Следующий заголовок CSP разрешит выполнение скрипта:
Content-Security-Policy: script-src 'unsafe-hashes' 'sha256-{HASHED_EVENT_HANDLER}'
Небезопасные выражения eval
Выражение источника 'unsafe-eval' управляет несколькими способами выполнения скриптов, создающими код из строк. Если у страницы есть заголовок CSP, а 'unsafe-eval' не указано в директиве script-src, следующие методы будут заблокированы и не окажут никакого эффекта:
eval()Function()-
При передаче строкового литерала таким методам, как
setTimeout("alert(\"Hello World!\");", 500); -
window.execScript()(только в IE < 11)
Небезопасное выполнение WebAssembly
Выражение источника 'wasm-unsafe-eval' управляет выполнением WebAssembly. Если у страницы есть заголовок CSP, а 'wasm-unsafe-eval' не указано в директиве script-src, загрузка и выполнение WebAssembly на странице блокируются.
Выражение источника 'wasm-unsafe-eval' более конкретно, чем 'unsafe-eval', которое разрешает как компиляцию (и создание экземпляров) WebAssembly, так и, например, использование операции eval в JavaScript. Если используется ключевое слово источника 'unsafe-eval', оно переопределяет любое вхождение 'wasm-unsafe-eval' в политике CSP.
Content-Security-Policy: script-src 'wasm-unsafe-eval'
strict-dynamic
Выражение источника 'strict-dynamic' указывает, что доверие, явно предоставленное скрипту в разметке с помощью nonce или хеша, распространяется на все скрипты, загруженные этим корневым скриптом. При этом все списки разрешённых источников и такие выражения источников, как 'self' или 'unsafe-inline', игнорируются.
Например, политика script-src 'strict-dynamic' 'nonce-R4nd0m' https://allowlisted.example.com/ позволит загрузить корневой скрипт с <script nonce="R4nd0m" src="https://example.com/loader.js"> и распространит это доверие на любой скрипт, загруженный с помощью loader.js, но запретит загрузку скриптов с https://allowlisted.example.com/, если они не сопровождаются nonce или загружаются доверенным скриптом.
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-someNonce'
Или:
Content-Security-Policy: script-src 'strict-dynamic' 'sha256-base64EncodedHash'
Можно развернуть strict-dynamic с обратной совместимостью без необходимости определять пользовательский агент. Политика:
Content-Security-Policy: script-src 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic'
будет работать как 'unsafe-inline' https: в браузерах с поддержкой CSP1, как https: 'nonce-abcdefg' в браузерах с поддержкой CSP2 и как 'nonce-abcdefg' 'strict-dynamic' в браузерах с поддержкой CSP3.
Разрешение правил спекулятивной загрузки
Чтобы добавить правила спекулятивной загрузки в элемент script (см. также <script type="speculationrules">), необходимо использовать директиву script-src с одним из источников 'inline-speculation-rules', источником хеша или источником nonce. Например:
Content-Security-Policy: script-src 'inline-speculation-rules'
Спецификации
Совместимость с браузерами
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari для iOS | Samsung Internet | WebView для Android | WebView для iOS | |
script-src |
25 | 14 | 23 | 15 | 7 | 25 | 23 | 14 | 7 | 1.5 | 4.4 | 7 |
external_scripts |
59 | 79 | 116 | 46 | 15.6 | 59 | 116 | 43 | 15.6 | 7.0 | 59 | 15.6 |
inline-speculation-rules |
110 | 110 | Нет | 96 | 26.2 | 110 | Нет | 74 | 26.2 | 21.0 | 110 | Нет |
trusted-types-eval |
145 | 145 | 148 | 129 | 26 | 145 | 148 | 96 | 26 | Нет | 145 | 26 |
wasm-unsafe-eval |
97 | 97 | 102 | 83 | 16 | 97 | 102 | 68 | 16 | 18.0 | 97 | 16 |
См. также
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src