Content Security Policy (CSP) - заголовок відповіді, яким сервер каже браузеру, звідки дозволено завантажувати й виконувати ресурси на цій сторінці: скрипти, стилі, зображення, шрифти, фрейми, запити fetch.
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-r4nd0m'; img-src 'self' https://cdn.example.com; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Головна ціль - зменшити наслідки XSS. Навіть якщо нападник зміг вставити <script> у сторінку, браузер його не виконає: скрипт не має дозволеного джерела чи правильного nonce. CSP - другий рубіж: основний захист від XSS - екранування виводу, а CSP спрацьовує, коли екранування десь пропустили.
Основні директиви:
default-src- запасне правило для всіх типів ресурсів;script-src,style-src,img-src,connect-src(куди можна робитиfetch/WebSocket),font-src,frame-src;object-src 'none'- заборона застарілих плагінів;base-uri 'self'- захист від підміни<base>, через яку відносні посилання на скрипти ведуть на чужий домен;form-action- куди можна відправляти форми;frame-ancestors- хто може вбудовувати сторінку у фрейм (захист від clickjacking).
Що CSP блокує за замовчуванням, щойно задано script-src:
- інлайнові скрипти (
<script>...</script>,onclick="...",javascript:у посиланнях); eval()іnew Function()- без'unsafe-eval'.
Чого CSP не дає:
- не захищає від CSRF, SQL-ін'єкцій та логічних помилок;
'unsafe-inline'уscript-srcмайже повністю знецінює захист від XSS - тому інлайнові скрипти дозволяють через nonce чи хеш, а не через'unsafe-inline'.
У Laravel вбудованого middleware для CSP немає: заголовок ставлять власним middleware або пакетом spatie/laravel-csp, а Vite::useCspNonce() додає nonce до тегів, які генерує @vite.