CSP does not fix XSS. It limits the blast radius if you are lucky
Content Security Policy is useful, but it is not a substitute for output encoding, safe DOM APIs, and removing unsafe sinks.
Content Security Policy is one of the most misunderstood defenses in web security.
People treat it like a patch. It is not a patch. CSP is a browser policy that can block some script execution paths after the application has already produced unsafe output. That is valuable. It is also late.
If untrusted input reaches an executable context, the application still has an XSS bug.
A strict policy changes the payload class
A good CSP can kill lazy payloads:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
Inline event handlers such as onerror=alert(1) should fail. javascript: URLs should usually fail. Remote script injection should fail unless the source is allowed.
That does not mean the target is safe. It means the tester has to ask better questions. Are there same-origin script gadgets? JSONP endpoints? Angular template injection? A nonce reused across responses? A legacy route with unsafe-inline? A base tag issue that changes script resolution?
CSP narrows the attack surface. It rarely eliminates it.
Weak policies are worse than no policy in reports
This policy looks serious and often is not:
Content-Security-Policy: script-src 'self' 'unsafe-inline' https:
unsafe-inline permits the exact class of payload many teams think CSP blocks. https: allows scripts from any HTTPS origin. A wildcard CDN source can be almost as bad if users can upload JavaScript or control a path on that origin.
The report should not just say "CSP bypassed." Say what was allowed and why it mattered.
CSP is not output encoding
The fix for reflected HTML injection is still contextual output encoding. The fix for DOM XSS is still removing unsafe sinks or sanitizing with a library that understands HTML, SVG, MathML, URL attributes, and browser quirks. The fix for template injection is still avoiding untrusted template compilation.
CSP helps when a mistake slips through.
It should not be the primary control.
Testing with CSP enabled
When a payload fails under CSP, capture the console error. It often tells you exactly which directive blocked execution.
Refused to execute inline event handler because it violates:
"script-src 'self'"
That is useful evidence. It proves the injection reached a dangerous shape, but execution was blocked by policy. Depending on program rules, that may still be reportable as blocked XSS, HTML injection, or a defense-in-depth issue.
Be precise. Security teams hate vague CSP claims, and they are right to hate them.