Що таке CSP і як захистити сайт із нею?
Автор: Редакція Domeny.ForSale Опубліковано
Коротко: CSP, тобто Content Security Policy, — це механізм безпеки браузера, який дає змогу визначити, звідки сторінка може завантажувати ресурси та який код виконувати. Він допомагає обмежити наслідки XSS — впровадження стороннього скрипту на сторінку, а відповідна директива також захищає від вбудовування сайту в небажані фрейми. Політику найкраще передавати в заголовку відповіді HTTP і спочатку перевірити без блокування ресурсів.
Як працює CSP і від чого захищає?
Зазвичай браузер завантажує ресурси, зазначені в коді сторінки: скрипти, таблиці стилів, зображення чи шрифти. CSP додає до цього набір правил. Якщо ресурс або спосіб виконання коду не відповідає політиці, браузер блокує його та записує інформацію про порушення в інструментах розробника.
Основне призначення CSP — обмежувати атаки XSS (cross-site scripting). Під час такої атаки зловмисник домагається виконання свого скрипту в контексті чужого сайту. Наприклад, уразливість у формі коментарів може дати змогу вставити код JavaScript замість звичайного тексту. Достатньо сувора CSP може запобігти виконанню цього коду, навіть якщо застосунок помилково розмістить його на сторінці.
CSP також допомагає протидіяти клікджекінгу: вбудовуванню сторінки у фрейм, коли користувача спонукають натискати її елементи, приховані під оманливим накладеним шаром. За цей захист відповідає директива frame-ancestors. Саме лише налаштування правил для скриптів його не забезпечує.
Проте CSP не усуває вразливостей застосунку. Як і раніше, потрібні правильне кодування вихідних даних, безпечне опрацювання користувацького вмісту та оновлення програмного забезпечення. Політика є додатковим рівнем захисту, а не заміною цих заходів.
Де налаштовують політику CSP?
Рекомендований спосіб — заголовок відповіді HTTP з назвою Content-Security-Policy. Його може додавати застосунок, вебсервер, зворотний проксі або CDN. Заголовок має надходити до браузера разом із документом HTML, якого він стосується.
Частину правил можна також передати через тег meta з атрибутом http-equiv="Content-Security-Policy". Цей спосіб має обмеження: політика починає діяти лише після зчитування тегу, не підтримує режим звітування без блокування та директиву frame-ancestors. Якщо маєте доступ до налаштувань відповіді HTTP, виберіть заголовок.
Також перевірте, чи CSP вже не додає інший рівень інфраструктури. Кілька політик застосовуються одночасно — новий заголовок не замінює попередній автоматично. Тому він може додатково обмежити роботу сайту.
Основні директиви та приклад заголовка
Директива — це окреме правило політики. Директиви відокремлюють крапками з комою, а після їхніх назв указують дозволені джерела або спеціальні значення.
| Директива | Що контролює |
|---|---|
default-src | Типові джерела для багатьох типів ресурсів, якщо для них немає окремого правила |
script-src | Джерела скриптів та умови виконання JavaScript |
style-src | Джерела таблиць стилів і правила використання вбудованих стилів |
img-src | Джерела зображень |
connect-src | З’єднання, ініційовані, зокрема, через fetch і WebSocket |
object-src | Вбудовані об’єкти, які обробляють такі елементи, як object |
base-uri | Адреси, дозволені в елементі base |
frame-ancestors | Сторінки, які можуть вбудовувати документ у фрейм |
Для простого сайту, який використовує лише власні файли, відправною точкою може бути:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Значення 'self' означає те саме походження: однакові схему, ім’я хоста й порт. 'none' не дозволяє жодного джерела. Наведений приклад забороняє вбудовувати сторінку у фрейми, а також блокує, зокрема, скрипти, записані безпосередньо в HTML, та атрибути подій, як-от onclick.
Це не універсальна конфігурація. Якщо сайт використовує зовнішню платіжну систему, аналітику чи шрифти, потрібно визначити необхідні джерела й додати їх до відповідних директив. default-src не замінює всіх правил — наприклад, frame-ancestors потрібно оголошувати окремо.
Як упровадити CSP без випадкового блокування сайту?
Найбезпечніше спочатку з’ясувати, від яких ресурсів і сервісів насправді залежить сайт, і лише потім увімкнути блокування.
- Складіть перелік ресурсів та інтеграцій. Врахуйте не лише головну сторінку, а й вхід в обліковий запис, форми, платежі та кабінет користувача.
- Установіть заголовок
Content-Security-Policy-Report-Only. Браузер перевірятиме відповідність запропонованій політиці та повідомлятиме про порушення, але не блокуватиме відповідні дії чи ресурси. Автоматичне збирання звітів потребує додаткового налаштування механізму звітування та приймача звітів. - Перевірте повні сценарії користувача. Перегляньте консоль і мережеву панель браузера. Відокремте потрібні ресурси від зайвих інтеграцій і запитів, що надходять від розширень браузера.
- Виправте правила та код. Після тестування перенесіть перевірену політику в заголовок
Content-Security-Policy, а після впровадження відстежуйте помилки.
Не позбувайтеся попереджень, бездумно додаючи *, 'unsafe-inline' чи 'unsafe-eval'. Такі винятки можуть суттєво послабити захист. Для потрібних вбудованих скриптів можна використовувати nonce — непередбачуване значення, що генерується для кожної відповіді, — або хеш, тобто контрольний відбиток вмісту конкретного скрипту. Значення nonce в заголовку та в елементі скрипту мають збігатися; стала величина, вставлена в конфігурацію, цього завдання не виконує.
Почніть із політики в режимі звітування в тестовому середовищі та пройдіть увесь шлях від входу на сайт до надсилання форми чи завершення покупки. Це покаже, які дозволи справді потрібні, перш ніж CSP почне блокувати ресурси для користувачів.
Дивіться також: Що таке MCP?
