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 - це зло" і, швидше за все, це причина для майбутнього кінця світу. Ці люди помиляються. Звичайно, ви можете однозначно пробити основні дірки в безпеці вашого сайту за допомогою 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