Як настроїти Content Security Policy (CSP)

Три роки тому організацією Mozilla Foundation було розроблено новий стандарт політики безпеки, який запобігає XSS-атакам та іншим пов'язаним з ним видам атак забороняючи підвантажувати та виконувати скрипти із заборонених ресурсів. Називається вінContent Security Policy (CSP), що в перекладі означає «Політика безпеки контенту».
На момент написання статті стандарт CSP перебуває у статусі Candidate Recommendation, що означає можливе ухвалення цього стандарту у майбутньому W3C консорціумом. На даний момент усі популярні браузери підтримують цей стандарт.
| Chrome | 25+ | Повна підтримка |
| Firefox | 23+ | |
| Opera | 15+ | |
| Яндекс.Браузер | ||
| Firefox | 4-22 | Підтримують нестандартний заголовок X-Content-Security-Policy та частково підтримують стандартний |
| IE | 10+ | |
| Chrome | 14-24+ | Підтримують нестандартний заголовок X-Webkit-CSP та частково підтримують стандартний |
| Safari | 5-7 |
Як відсутність CSP може зашкодити сайту?
Зміст Content Security Policy
Насправді Content Security Policy — це заголовок, який сервер надсилає браузеру. Давайте розберемо детальніше з чого він складається.
Зараз ще трохи теорії, і потім відразу перейдемо до практики, зазнайте 😉
| ‘self’ | Визначає поточний хост. |
| ‘none’ | Забороняє все. «You shall not pass!» 🙂 |
| 'unsafe-inline' | Використовується лише у директивах script-src та style-src. Дозволяє виконувати inline-скрипти на сторінці. Не рекомендую використовувати це ключове слово, т.к. це розв'язує руки зловмисникові та дає право виконувати будь-які інлайнові скрипти на сторінці. Простими словами, це дірка у безпеці. |
| ‘unsafe-eval’ | Використовується тільки в script-src і дозволяє кодогенерацію, наприклад: eval, new Function, setTimeout(var foo = bar , 7) |
Встановлюємо Content Security Policy на сайт
Як я вже писав вище, CSP - це звичайний http заголовок, який можна спостерігати в консолі Google Chrome, поряд з іншими заголовками:

Щоб краще зрозуміти як працює Content Security Policy, давайте трохи поекспериментуємо. Створіть файл index.php та напишіть у нього наступний код:
Зверніть увагу, що в http заголовку я вказавContent-Security-Policy-Report-Only він аналогічний Content-Security-Policy, з тією різницею, що не блокує ресурси, а тільки повідомляє про порушення. Надзвичайно корисна штука при тестуванні системи перед використанням!
Давайте розберемося, що ми понаписали. Насамперед ми вказали в http заголовку директиву default-src 'self', що означає, що підвантажувати ресурси можна тільки зі свого хоста. Будь-які інлайн скрипти та css заборонені. Ок, йдемо далі і бачимо:
Тобто. спробуємо виконати інлайн скрипт та завантажити картинку зі стороннього хоста. І подивимося, як відреагує наш бравий захисник:

Тепер давайте змінимо заголовок з Content-Security-Policy-Report-Only на Content-Security-Policy і подивимося, що буде:


Тепер можете експериментувати самостійно. Вам знадобляться дві таблички вище у статті, в яких ми розглянули директиви та ключові слова для вказівки хостів. Спробуйте замінити 'self' на http://zabolotskikh.com/ і подивіться що станеться - картинка зможе завантажитись, оскільки її сервер був вказаний у білому списку.
Хочу звернути вашу увагу, що хост бажано вказувати з протоколом, тому що інакше протокол буде взято з поточного хоста. Наприклад, якщо ви вкажіть хост як zabolotskikh.com, а ваш сервер працює за протоколом https, то в білому списку виявиться https://zabolotskikh.com/.
Обробка звітів
Вся принадність цієї політики в тому, що окрім блокування, ми також можемо збирати звіти про порушення! Пам'ятаєте у прикладі в http заголовку ми вказали url report-uri http://localhost/csp/collector.php для скидання звітів? Як не складно здогадатися на цей URL будуть надсилатися всі звіти про порушення. От так виглядає звіт про порушення (у форматі JSON):
З цим звітом ви можете робити все, що завгодно, наприклад зберігати в базу, відправляти на пошту. Я пропоную записувати всі порушення у csv файл. Давайте зробимо це!
Створіть файл collector.php та напишіть у нього наступні рядки:
Тепер знову оновіть сторінку і подивіться в директорію http://localhost/csp/. У вас має з'явитися файл report.csv з двома рядками коду:

Корисні матеріали по Content Security Policy
А чи можна докладніше, що куди писати в wordpress?