Политика защиты содержимого
===========================

Политика защиты содержимого (англ. Content Security Policy) автоматически применяется ко всем расширениям, разработанным с использованием WebExtension API. Она ограничивает источники, из которых расширение может загружать <script> и <object> (en-US) ресурсы, и препятствует потенциально опасным практикам, например использованию `eval()`.

Статья в краткой форме объясняет значимость этой политики, каковы её изначальные правила, как они влияют на расширение, и как расширение может изменять эти правила.

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

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


```html
<!doctype html>

<html>
  <head>
    <meta charset="utf-8" />
  </head>

  <body>
    <!-- Некоторый HTML контент -->

    <!--
 Подключение сторонней библиотеки.
 Смотрите также https://developer.mozilla.org/ru/docs/Web/Security/Subresource\_Integrity.
 -->
    <script>
 src="https://code.jquery.com/jquery-2.2.4.js"
 integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI="
 crossorigin="anonymous">
 </script>

    <!-- Include my popup's own script-->
    <script src="popup.js"></script>
  </body>
</html>
```


В сравнении с веб-сайтами, расширения имеют доступ к дополнительному привилегированному API, так что вероятность получения к нему доступа сторонним кодом - это очень большой риск. По этой причине:

* довольно строгая политика по защите содержимого применяются изначально. Смотрите изначальные правила по защите содержимого.
* авторы расширений могут изменять изначальную политику, используя `content_security_policy` ключ в manifest.json, но даже в этом случае существуют ограничения на возможные разрешения. Для дополнительной информации смотрите `content_security_policy`.
Изначальные правила по защите содержимого
-----------------------------------------

Следующие правила по защите содержимого являются изначальными:
```

"script-src 'self'; object-src 'self';"
```


Они применяются к любому расширению, которое самостоятельно не указывает свою политику защиты, используя `content_security_policy` ключ в manifest.json. Это имеет следующие последствия:

* Вы можете загружать только локальные к расширению <script> и <object> ресурсы.
* Расширению не разрешено выполнять код, представленный в виде JavaScript строк.
* Встраиваемый (inline) JavaScript-код не будет выполняться.
### Расположение script и object ресурсов

Используя изначальную политику защиты содержимого, вы можете загружать только локальные к расширению <script> и <object> (en-US) ресурсы. Например, рассмотрите эту строку из документа расширения:


```html
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
```


Она не будет загружать запрашиваемый ресурс, и вы не сможете найти ни один ожидаемый от ресурса объект. К этой ситуации существует два решения:

* Скачать этот ресурс, упаковать его в ваше расширение и ссылаться к нему локально.
* Использовать ключ `content_security_policy` в manifest.json, чтобы позволить загрузку контента из вышеупомянутого источника..
### eval() и товарищи

Изначальная политика защиты содержимого не позволяет выполнять код из JavaScript строк. Это означает, что следующие примеры кода изначально запрещены:


```js
eval("console.log('some output');");
```



```js
window.setTimeout("alert('Hello World!');", 500);
```



```js
var f = new Function("console.log('foo');");
```

### Встраиваемый (inline) JavaScript

Изначальная политика защиты содержимого не позволяет выполнять JavaScript-код, встраиваемый в HTML теги. Это запрещает как выполнение JavaScript-кода вложенного прямо в `<script>` тег, так и выполнение вписанных в атрибут обработчиков событий, означая, что следующий код так же не будет работать:


```html
<script>
 console.log("foo");
</script>
```



```html
<div onclick="console.log('click')">Click me!</div>
```


Вместо того, чтобы использовать код `<body onload="main()">` для запуска вашего скрипта после загрузки страницы, поставьте обработчики событий на DOMContentLoaded (en-US) или load.