Content Security Policy Definition Content Security Policy (CSP) is a browser security control that tells the browser which sources and execution patterns are allowed for scripts, styles, images, frames, connections, and other resource types. Why it matters CSP is defense-in-depth for XSS and content injection, not a replacement for output encoding or safe templating. A strong policy can reduce exploitability when an injection bug exists, while a weak policy can create false confidence. How it works CSP controls 5 browser decisions: Script execution. Which scripts may load or execute. Resource loading. Which origins may provide images, styles, fonts, media, and frames. Network connections. Which endpoints JavaScript may connect to. Embedding. Who can frame the page and what the page can frame. Reporting. Where violations are reported. Example header: Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-random'; object-src 'none'; base-uri 'none'; frame-ancestors 'none' The bug is not absence of CSP alone. The bug is relying on CSP while allowing unsafe sources or inline execution that defeats the policy. Techniques / patterns Attackers test: script-src weaknesses: unsafe-inline, wildcards, broad CDNs, JSONP, upload origins missing nonces or reusable nonces object-src, base-uri, and frame-ancestors omissions bypassable trusted domains DOM XSS sinks under policy constraints report-only policies mistaken for enforcement Variants and bypasses CSP failure appears in 6 forms. 1. No policy The browser receives no meaningful execution restrictions. 2. Report-only policy Violations are reported but not blocked. 3. Unsafe inline execution unsafe-inline, unsafe hashes, or nonce misuse allows injected scripts. 4. Overbroad trusted sources Wildcards or broad CDNs allow attacker-controlled content from trusted origins. 5. Missing structural directives Missing base-uri, object-src, or frame-ancestors leaves bypass paths open. 6. Policy drift The policy grows permissive over time to support new features. Impact Ordered roughly by severity: XSS exploitability reduction or failure. Strong CSP can block injected script execution. Clickjacking and framing control. frame-ancestors protects sensitive pages. Data exfiltration reduction. connect-src limits where scripts can send data. Content injection containment. Resource restrictions reduce malicious loading. Telemetry. Reports reveal attempted violations and policy gaps. Detection and defense Ordered by effectiveness: Fix injection at the source first. Output encoding, safe templating, sanitization, and DOM safety are primary XSS defenses. Use nonce-based or hash-based script-src without unsafe inline execution. This is the most meaningful CSP control for modern XSS reduction. Set restrictive defaults and structural directives. default-src 'self', object-src 'none', base-uri 'none', and frame-ancestors reduce bypass space. Keep trusted origins narrow. Every allowed origin should be owned, necessary, and unable to host attacker-controlled scripts. Deploy with reporting and review violations. Report-only is useful during rollout, but final protection requires enforcement. What does not work as a primary defense CSP instead of output encoding. CSP is defense-in-depth, not the primary XSS fix. unsafe-inline. It usually defeats the point of script restrictions. Broad wildcards. *.cdn.example can include attacker-controlled paths. Report-only mode. It observes but does not block. Practical labs Use owned apps. Inspect policy curl -I https://app.example.test/ | rg -i "content-security-policy" Check whether the policy is enforced or report-only. Review risky directives curl -I https://app.example.test/ | rg -i "unsafe-inline|unsafe-eval|\\*|data:" Each risky source should have a justification. Test frame protection curl -I https://app.example.test/account | rg -i "frame-ancestors|x-frame-options" Sensitive pages should not be broadly frameable. Practical examples A site has XSS but a strong nonce-based CSP blocks script execution. A policy uses unsafe-inline, making it ineffective against many XSS bugs. A trusted CDN path allows user-uploaded JavaScript. frame-ancestors is missing on account settings. CSP report-only logs violations but does not block attacks. Related notes xss http-headers cors-misconfiguration open-redirect clickjacking Suggested future atomic notes nonce-based-csp csp-bypasses trusted-types frame-ancestors csp-reporting References Foundational: MDN Content Security Policy — https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP Testing / Lab: PortSwigger CSP — https://portswigger.net/web-security/cross-site-scripting/content-security-policy Foundational: OWASP Content Security Policy Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html ← PreviousCommand InjectionNext →CORS Misconfiguration Explore nearby notes Web SecurityClickjackingClickjacking is a UI redress attack where an attacker embeds a target page in a frame and tricks the user into clicking or typing into the real target UI while... Web SecurityAuthentication FlawsAuthentication flaws are weaknesses in how an application verifies identity. They include weak login logic, user enumeration, broken MFA flows, password reset... Web SecurityBot Detection SignalsBot detection signals are the observable clues a web application or edge service uses to classify traffic as human, benign automation, suspicious automation, or... Web SecurityBroken Access ControlBroken access control happens when an application fails to enforce what a caller is allowed to access or do. Web SecurityBusiness Logic VulnerabilitiesBusiness logic vulnerabilities are flaws in the intended workflow, assumptions, invariants, or rule design of an application, where the system behaves as coded but... Web SecurityCommand InjectionCommand injection occurs when an application builds an operating-system command from attacker-controlled input and executes it through a shell or process API...