Content-Security-Policy
Мета-тег позволяет уменьшить риск XSS атак, позволяя определить , где ресурсы могут быть загружены из, предотвращая браузеры от загрузки данных из любых других мест. Это мешает злоумышленнику внедрить вредоносный код на ваш сайт.
Я ударился головой о кирпичную стену, пытаясь понять, почему я получаю ошибки CSP одна за другой, и, похоже, нет четких и четких инструкций о том, как это работает. Итак, вот моя попытка объяснить некоторые кратко моменты CSP, в основном концентрируясь на вещах, которые мне было трудно решить.
Для краткости я не буду писать полный тег в каждом образце. Вместо этого я покажу только content
свойство, поэтому пример, который говорит, content="default-src 'self'"
означает следующее:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
1. Как разрешить несколько источников?
Вы можете просто перечислить ваши источники после директивы в виде списка, разделенного пробелами:
content="default-src 'self' https://example.com/js/"
Обратите внимание, что нет никаких кавычек вокруг параметров, кроме специальных , например 'self'
. Кроме того, нет двоеточия (:
после директивы ). Просто директива, затем разделенный пробелами список параметров.
Все ниже указанных параметров неявно разрешено. Это означает, что в приведенном выше примере это будут действительные источники:
https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js
Это, однако, не будет действительным:
http://example.com/js/file.js
^^^^ wrong protocol
https://example.com/file.js
^^ above the specified path
2. Как использовать разные директивы, что они делают каждый?
Наиболее распространенные директивы:
default-src
политика по умолчанию для загрузки JavaScript, изображений, CSS, шрифтов, запросов AJAX и т. д.
script-src
определяет действительные источники для файлов JavaScript
style-src
определяет действительные источники для CSS-файлов
img-src
определяет действительные источники для изображений
connect-src
определяет допустимые цели для XMLHttpRequest (AJAX), WebSockets или EventSource. Если предпринята попытка подключения к узлу, который здесь не разрешен, браузер выдаст 400
ошибку
Есть и другие, но это те, которые вам, скорее всего, понадобятся.
3. Как использовать несколько директив?
Вы определяете все свои директивы внутри одного мета-тега, заканчивая их точкой с запятой ( ;
):
content="default-src 'self' https://example.com/js/; style-src 'self'"
4. Как обрабатывать порты?
Все, кроме портов по умолчанию, необходимо явно разрешить, добавив номер порта или звездочку после разрешенного домена:
content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
Вышеуказанное приведет к:
https://ajax.googleapis.com:123
^^^^ Not ok, wrong port
https://ajax.googleapis.com - OK
http://example.com/free/stuff/file.js
^^ Not ok, only the port 123 is allowed
http://example.com:123/free/stuff/file.js - OK
Как я уже упоминал, вы также можете использовать звездочку, чтобы явно разрешить все порты:
content="default-src example.com:*"
5. Как обрабатывать разные протоколы?
По умолчанию разрешены только стандартные протоколы. Например, чтобы разрешить WebSockets, ws://
вы должны разрешить это явно:
content="default-src 'self'; connect-src ws:; style-src 'self'"
^^^ web sockets are now allowed on all domains and ports
6. Как разрешить файловый протокол file://
?
Если вы попытаетесь определить его как таковой, он не будет работать. Вместо этого вы позволите это с filesystem
параметром:
content="default-src filesystem"
7. Как использовать встроенные скрипты и определения стилей?
Если явно не разрешено, вы не можете использовать определения встроенного стиля, код внутри <script>
тегов или в свойствах тегов, как onclick
. Вы позволяете им так:
content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
Вам также необходимо явно разрешить встроенные изображения в кодировке base64:
content="img-src data:"
8. Как разрешить eval()
?
Я уверен, что многие скажут, что вы этого не сделаете, поскольку «eval is evil» и наиболее вероятная причина наступающего конца света. Эти люди будут неправы. Конечно, вы можете определенно пробить основные дыры в безопасности вашего сайта с помощью eval, но он имеет вполне допустимые варианты использования. Вы просто должны быть умны в использовании. Вы позволяете это так:
content="script-src 'unsafe-eval'"
9. Что именно 'self'
означает?
Вы могли бы взять 'self'
в виду localhost, локальную файловую систему или что-то на одном хосте. Это не значит, что-либо из этого. Это означает источники, которые имеют ту же схему (протокол), тот же хост и тот же порт, что и файл, в котором определена политика контента. Обслуживание вашего сайта по HTTP? Никаких https для вас тогда, если вы не определите это явно.
Я использовал 'self'
в большинстве примеров, поскольку обычно имеет смысл включать его, но это ни в коем случае не обязательно. Оставьте это, если вам это не нужно.
Но подожди минутку! Разве я не могу просто использовать content="default-src *"
и покончить с этим?
Нет. В дополнение к очевидным уязвимостям безопасности это также не будет работать так, как вы ожидаете. Хотя некоторые документы утверждают, что это разрешает все, это не так. Он не позволяет вставлять или убивать, поэтому, чтобы действительно сделать ваш сайт более уязвимым, вы должны использовать это:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
... но я верю, что ты не будешь.
Дальнейшее чтение:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy