Політики безпеки та CSP
1) Навіщо потрібні політики безпеки
Сучасний фронтенд і API залежать від безлічі джерел (CDN, аналітика, PSP, 3DS, чати). Без жорстких політик підвищуються ризики XSS, клікджекінгу, витоків даних і викрадень сесій. Політики безпеки обмежують те, що дозволено за замовчуванням, переводячи браузер в модель «дозволено тільки явно» (allow-list).
2) Базові стовпи
CSP (Content Security Policy) - централізоване «меню» дозволених джерел і поведінки JS/CSS/медіа.
Trusted Types - захист від DOM-XSS на рівні типів.
SRI (Subresource Integrity) - контроль цілісності скриптів/стилів.
COOP/COEP/CORP - жорстке ізолювання контекстів і ресурсів між джерелами.
Fetch Metadata («Sec-Fetch-») - серверне рішення для фільтрації крос-сайтових запитів.
CORS - політика міждоменного доступу до API.
Класичні заголовки: HSTS, `X-Frame-Options`/`frame-ancestors`, `Referrer-Policy`, `Permissions-Policy`, SameSite-cookies.
3) CSP: Основа та принципи
3. 1 Директиви (ключові)
«default-src» - дефолт для інших директив.
'script-src'- джерела JS, nonce/hash,'strict-dynamic','report-sample'.
'style-src'- джерела CSS; мінімізувати'unsafe-inline'.
`img-src`, `font-src`, `media-src`, `object-src` (обычно `none`).
«connect-src» - мережеві запити (XHR/fetch/WebSocket).
«frame-src »/« child-src» - сторонні фрейми (PSP, 3DS).
«frame-ancestors» - хто може вбудовувати наш сайт (анти-клікджекінг).
'base-uri'- заборона підміни'< base>'.
'form-action'- куди дозволено саблітити форми.
'upgrade-insecure-requests','block-all-mixed-content'- боротьба з міксом HTTP/HTTPS.
'report-uri '/' report-to'- куди слати порушення.
3. 2 Nonce и hash
Nonce-підхід: на кожен HTTP-відповідь генерувати криптослучайний'nonce', додавати до inline-скриптів'< script nonce =""...>'і в'script-src'nonce-... ".
Hash-підхід: фіксований хеш вмісту інлайну. Підходить для статичного HTML, незручний при динаміці.
`strict-dynamic`: довіряти тільки скриптам, завантаженим «довіреним» скриптом (з nonce/hash). Прибирає необхідність перераховувати цільові домени при динамічному завантаженні, але вимагає modern-браузерів.
3. 3 Заборона'unsafe- '
Уникати'unsafe-inline','unsafe-eval'. Якщо фреймворк вимагає eval (наприклад, source-map в dev), включати тільки на dev.
Для стилів - використовувати «nonce» або «hash», по можливості без інлайнів.
3. 4 Приклад суворої CSP (бойовий орієнтир)
Content-Security-Policy:
default-src 'none';
base-uri 'self';
object-src 'none';
script-src 'self' 'nonce-{RANDOM}' 'strict-dynamic' https://www. googletagmanager. com;
style-src 'self' 'nonce-{RANDOM}';
img-src 'self' data: https://images. example-cdn. com;
font-src 'self' https://fonts. gstatic. com;
connect-src 'self' https://api. example. com wss://ws. example. com;
frame-src https://3ds. psp. com https://pay. psp. com;
frame-ancestors 'none';
form-action 'self' https://pay. psp. com;
upgrade-insecure-requests;
report-to csp-endpoint; report-sample
4) Trusted Types (DOM-XSS)
Увімкніть директиву: `Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app default`.
Створіть єдину політику в коді ('window. trustedTypes. createPolicy('app', { createHTML() {... } })`).
Забороняйте небезпечні присвоювання ('element. innerHTML =...`) без Trusted Types.
Інтеграція з фреймворками (React/Angular/Vue): використовуйте безпечні API рендеринга, уникайте небезпечних dangerouslySetInnerHTML.
5) SRI (цілісність CDN)
Для зовнішніх'< script> '/' <link>'використовуйте'integrity =» sha256- «... crossorigin =» anonymous»'.
SRI доповнює, а не замінює CSP. При оновленні версії CDN - оновлюйте хеш.
6) Клікджекінг і фрейми
Сучасний спосіб - «frame-ancestors» (замінює застарілий «X-Frame-Options»).