# Content-Security-Policy (CSP)

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

Есть [CSPv1](https://www.w3.org/TR/CSP1/) (объявлен deprecated), сейчас уже [CSPv2](https://www.w3.org/TR/CSP2/) и готовится [CSPv3](https://www.w3.org/TR/CSP/).

## 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 (не все правила можно сюда записать).&#x20;

Есть ресурс, который проверяет, как настроен 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.&#x20;

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

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

Пример:&#x20;

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

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

```markup
<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>.
