Cross-Site Scripting (XSS) remains one of the most dangerous frontend vulnerabilities. Even with input validation and sanitization, a single missed edge case can lead to account takeover, data theft, or phishing. Content Security Policy (CSP) acts as the final and most powerful defense often called the XSS Kill Switch.

This article explains CSP in a practical, frontend-focused way, covering:

  • Allowed Sources
  • Script Nonces
  • Report-Only Mode
  • CSP Reporting (report-uri / report-to)

What is CSP?

Content Security Policy is an HTTP response header that tells the browser what resources are allowed to load and execute on a page.

CSP does not remove XSS bugs. It prevents malicious scripts from executing even if XSS exists.

Why CSP is Needed

Without CSP, the browser executes any script coming from the page:

<script>alert('XSS')</script>

With CSP enabled, the browser blocks this script unless it explicitly matches allowed rules.

This makes CSP the last line of defense when all other protections fail.

Allowed Sources (Whitelist Model)

What it means

CSP works on a deny-by-default model. You explicitly whitelist trusted sources; everything else is blocked.

Example

Content-Security-Policy: default-src 'self'

Explanation:

  • 'self' allows resources only from the same origin
  • External scripts are blocked

Script Source Example

Content-Security-Policy: script-src 'self' https://cdn.example.com;

Allowed:

<script src="/app.js"></script>
<script src="https://cdn.example.com/lib.js"></script>

Blocked:

<script src="https://evil.com/xss.js"></script>

This prevents attackers from loading malicious JavaScript from external domains. Script Nonces (The Strongest XSS Defense)

What is a Nonce?

A nonce is a cryptographically random, single-use value generated per HTTP response. Only scripts with the correct nonce are allowed to execute.

CSP Header with Nonce

Content-Security-Policy: script-src 'self' 'nonce-abc123'

Allowed Script

<script nonce="abc123">
console.log('This script is allowed');
</script>

Blocked XSS Script

<script>alert('XSS')</script>

The attacker cannot guess the nonce, so injected scripts never execute even stored XSS is neutralized.

Report-Only Mode

What is Report-Only Mode?

CSP can run in monitoring mode where it does not block scripts but reports violations.

Example

Content-Security-Policy-Report-Only: script-src 'self';

Why it's Important

  • Safely test CSP in production
  • Identify scripts that would be blocked
  • Prevent accidental site breakage

Once confident, you can switch to enforcing CSP.

CSP Reporting (report-uri / report-to)

Purpose

When CSP blocks a resource, the browser sends a violation report to a specified endpoint.

report-uri (Legacy)

Content-Security-Policy:
script-src 'self';
report-uri /csp-report;

report-to (Modern)

Content-Security-Policy: script-src 'self'; report-to default;

Report-To: {
"group": "default",
"max_age": 10886400,
"endpoints": [{ "url": "https://example.com/csp-report" }]
}

Sample Report

{
"violated-directive": "script-src",
"blocked-uri": "https://evil.com/xss.js"
}

These reports help detect attacks and improve security posture.

Dangerous CSP Configuration (Avoid This)

script-src 'self' 'unsafe-inline' 'unsafe-eval';

This configuration allows inline scripts and eval, defeating CSP's purpose.

Strong Production CSP Example

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-abc123';
  style-src 'self';
  img-src 'self' data:;
  connect-src 'self' https://api.example.com;
  object-src 'none';
  frame-ancestors 'none';

CSP vs XSS (Interview Summary)

CSP restricts where scripts can come from and which scripts can run. Even if XSS exists, CSP blocks execution, making it one of the strongest frontend security controls.

Final Thoughts

CSP should never replace input validation or sanitization but when combined with them, it dramatically reduces XSS risk. For modern frontend applications, especially SPAs and fintech apps, a strong CSP is non-negotiable.

If you care about frontend security, CSP is not optional it is essential.