Content-Security-Policy (CSP)

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

Есть CSPv1 (объявлен deprecated), сейчас уже CSPv2 и готовится CSPv3.

CSPv1

С 2010-ого года. Браузеры на тот момент каждый реализовывал эту фичу как экспериментальную, под своими заголовками:

  • Firefox, IE: X-Content-Security-Policy

  • Chrome: X-WebKit-CSP.

CSPv2

Действующий стандарт. Заголовок: Content-Security-Policy.

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

Разные заметки о CSP

Сюда входят правила из разряда:

  • скриптам с каких доменов разрешено исполняться на этой странице (script-src);

  • каким доменам разрешено встраивать эту страницу в iframe (frame-ancestors);

  • разрешено ли использование base-тегов (base-uri).

Есть директива default_src — она определяет действия по-умолчанию, все остальные директивы переписывают (или дополняют?) default_src.

Может определяться в заголовке Content-Security-Policy, или в теге meta (не все правила можно сюда записать).

Есть ресурс, который проверяет, как настроен CSP у вас: https://csp-evaluator.withgoogle.com/

Не настроеный CSP вместе с отстутсвием настройки X-Frame-Options -> получаем Clickjacking.

Примеры директив

Можно загружать только с того же origin:

script-src 'self';

Можно загружать только с определенного домена:

script-src https://scripts.example.com;

Есть при этом нюансы: не стоит доверять CDNs, например: ajax.googleapis.com.

Есть другие механизмы помимо перечисления доменов для создания белых списков источников — nonces и hashes:

  • CSP директива может указать случайное число — nonce — и такое же значение должно быть в теге скрипта. Если значения не совпадут, скрипт не запустится. Чтобы этта мера была эффективна как мера контроля, nonce должен быть случайным, непредсказуемым для атакующего.

Пример:

script-src 'nonce-s0m3-rand0m-valu3';

И в теге инлайн скрипта указываем наш nonce:

<script>
    // этот скрипт не запустится, тк здесь нет атрибута nonce
</script>
<script nonce="wr0ng-valu3">
    // этот скрипт не запустится, тк здесь не правильное значение nonce
</script>
<script nonce="s0m3-rand0m-valu3">
    // этот скрипт отработает
</script>
  • CSP директива может указать hash содержимого скрипта. Если хеш не совпадет, скрипт не запустится.

Другие заметки

Сайты часто настраивают CSP для таких ресурсов как скрипты script, но не блокируют запросы изображений. Таким образом часто можно выполнять запросы на сторонние серверы через тег img. В некоторых случаях это может раскрыть CSRF-токен.

Некоторые браузеры, такие как Chrome, имеют встроенную защиту против атак класса dungling markup, и блокируют запросы, содержащие не ascii-символы, незакодированные переносы строк или кавычки.

report-uri — сообщает о некорректных обращениях в обход CSP

Strict dynamic — паттерн, при котором в CSP добавляется один JS-файл с nonce как разрешенный для выкачки, а он подтягивает все остальные зависимости.

Есть немалое количество обходов CSP, например, через angular. Суть: мы добавляем элемент из разрешенных, и через него подтягиваем нудные файлы, делаем запросы.

Не использовать unsafe-inline — это равносильно отключению CSP.

Trusted types — позволяет ограничить типы поступаемых аргументов в функции, коллбеки и тд (защитить от DOM XSS)

Papers

Здесь можно подробно прочитать: https://habr.com/ru/company/nix/blog/271575/

Tools

Сервис проверки безопасности CSP от гугла — https://csp-evaluator.withgoogle.com.

Last updated