CSP (Content Security Policy) là HTTP header whitelist trusted sources cho scripts, styles, images, fonts — defense in depth chống XSS. default-src: fallback cho directives không specify; script-src: chỉ load scripts từ approved sources; style-src, img-src, font-src, connect-src (fetch/XHR), frame-src, form-action.
- Directives: 'self' (same origin), 'none' (block all), specific domains, 'unsafe-inline' (allow inline — weakens CSP), 'unsafe-eval' (allow eval — dangerous).
- Strict CSP với nonces: script-src 'nonce-{random}' — mỗi request tạo random nonce, inline scripts chỉ chạy nếu có matching nonce attribute; phòng chống injection tốt hơn domain whitelist.
- Hash-based: sha256-{base64hash} thay vì nonce cho static inline scripts.
- Report-Only mode: Content-Security-Policy-Report-Only header — observe violations mà không block, collect reports để debug trước khi enforce. report-uri/report-to: endpoint nhận violation reports dạng JSON — essential để monitor và catch issues sau deploy (ví dụ third-party script bị block).
- Trusted Types API: ngăn DOM XSS bằng cách enforce typed DOM operations — require-trusted-types-for 'script'.
- Lưu ý: CSP với 'unsafe-inline' và 'unsafe-eval' cho toàn bộ site thực tế vô dụng — common mistake khi copy từ examples mà không hiểu.
- Bắt đầu với Report-Only, collect violations, fix, rồi enforce.
CSP (Content Security Policy) is an HTTP header that whitelists trusted sources for scripts, styles, images, and fonts — defense in depth against XSS. default-src: fallback for unspecified directives; script-src: only load scripts from approved sources; style-src, img-src, font-src, connect-src (fetch/XHR), frame-src, form-action.
- Directives: 'self' (same origin), 'none' (block all), specific domains, 'unsafe-inline' (allow inline — weakens CSP), 'unsafe-eval' (allow eval — dangerous).
- Strict CSP with nonces: script-src 'nonce-{random}' — each request generates a random nonce; inline scripts only execute if they have a matching nonce attribute; better protection than a domain allowlist.
- Hash-based: sha256-{base64hash} instead of a nonce for static inline scripts.
- Report-Only mode: Content-Security-Policy-Report-Only header — observe violations without blocking, collect reports to debug before enforcing. report-uri/report-to: endpoint that receives violation reports as JSON — essential for monitoring and catching issues after deployment (e.g., a third-party script being blocked).
- Trusted Types API: prevents DOM XSS by enforcing typed DOM operations — require-trusted-types-for 'script'.
Pitfall: a CSP with 'unsafe-inline' and 'unsafe-eval' applied globally is effectively useless — a common mistake when copying examples without understanding them.