Complete Guide to CSP (Content Security Policy)
The Ultimate Guide to Modern Content Security Policy Level 3: Nonces, Hashes, Directives, and Eliminating XSS
Web Protocols & Security Architecture Research
What is Complete Guide to CSP (Content Security Policy)?
TL;DR — Key Engineering Takeaways
- CSP is the strongest browser-native mitigation against Cross-Site Scripting (XSS) attacks.
- By default, a strict CSP disables inline script execution (`<script>alert(1)</script>`) and string-to-code execution (`eval()`).
- Modern CSP Level 3 favors nonce-based policies (`script-src 'nonce-rAnd0m' 'strict-dynamic'`) over brittle domain allowlists.
- `Content-Security-Policy-Report-Only` allows testing policies in production by logging violations without breaking legitimate site functionality.
- Directives cascade: if a specific directive (e.g. `img-src`) is not declared, the browser falls back to `default-src`.
Core Concepts & Architecture
default-src
DirectivesThe fundamental fallback directive governing all unspecified resource types (scripts, images, fonts, styles).
Cryptographic Nonces
NoncesSingle-use random tokens generated per-request and passed in both the CSP header and `<script nonce="...">` tags.
strict-dynamic
ModernCSPCSP Level 3 directive allowing a trusted script with a valid nonce to load subsequent child scripts without domain allowlists.
frame-ancestors
ClickjackingReplaces legacy `X-Frame-Options` by declaring which parent origins are allowed to embed the page in iframes.
report-to / report-uri
TelemetrySpecifies an endpoint where the browser dispatches JSON violation reports whenever a policy breach is detected.
How does Complete Guide to CSP (Content Security Policy) work?
When the browser receives an HTTP response containing a `Content-Security-Policy` header, its security manager parses the directive list into a memory policy tree. As the HTML parser encounters external resources or inline scripts, it queries the policy engine. If an inline script lacks a matching cryptographic nonce or SHA-256 hash, or if an image originates from an unlisted host, the browser blocks execution immediately and posts a JSON violation report.
Server Generates Nonce
For every incoming HTTP request, backend generates a high-entropy random base64 string.
const nonce = crypto.randomBytes(16).toString("base64");Header Injection
Server sends CSP header binding the nonce to script-src and setting default restrictions.
Content-Security-Policy: default-src 'self'; script-src 'nonce-${nonce}' 'strict-dynamic';HTML Template Rendering
Server attaches the identical nonce attribute to authorized script tags in HTML markup.
<script nonce="${nonce}" src="/app.js"></script>Browser Evaluation
Browser compares script tag nonce against header value; matches proceed, mismatches trigger violations.
Match: Execute script. Mismatch or Missing: Drop & Log Violation.Violation Reporting
Browser transmits structured JSON report to configured report-to endpoint for observability.
POST /csp-reports {"csp-report": {"blocked-uri": "eval", "violated-directive": "script-src"}}How do you implement Complete Guide to CSP (Content Security Policy) in practice?
Google-Recommended Strict Nonce-Based CSP (Level 3)
httpContent-Security-Policy:
default-src 'self';
script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' 'strict-dynamic' https: 'unsafe-inline';
style-src 'self' 'unsafe-inline';
object-src 'none';
base-uri 'self';
frame-ancestors 'none';Engineering Details: The modern gold standard: `'strict-dynamic'` trusts scripts loaded by nonced scripts; `'unsafe-inline'` is ignored by modern browsers when a nonce is present, providing backwards compatibility for legacy browsers.
Express.js Implementation using Helmet Middleware
javascriptimport express from "express";
import helmet from "helmet";
import crypto from "crypto";
const app = express();
// Generate cryptographic nonce per-request
app.use((req, res, next) => {
res.locals.cspNonce = crypto.randomBytes(16).toString("base64");
next();
});
app.use((req, res, next) => {
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`, "'strict-dynamic'"],
objectSrc: ["'none'"],
baseUri: ["'self'"],
upgradeInsecureRequests: [],
},
})(req, res, next);
});Engineering Details: Generates a unique 128-bit cryptographic nonce on every request and injects it into both Helmet CSP and template response locals.
Where and why is Complete Guide to CSP (Content Security Policy) used in production?
Preventing malicious third-party tag managers or browser extensions from exfiltrating medical records.
Locking down `connect-src` and `form-action` strictly to internal API domains so stolen data cannot be transmitted to external servers.
Stopping e-skimming attacks where compromised third-party scripts steal checkout credit card details.
Using strict CSP `script-src` and `connect-src` restrictions to block unauthorized external script injection at checkout steps.
What are common mistakes and misconceptions with Complete Guide to CSP (Content Security Policy)?
Impact: Allows any injected `<script>evil()</script>` payload to run, rendering CSP almost entirely ineffective against XSS.
Recommended Correction: Migrate inline JavaScript to external files or supply cryptographic nonces on all script tags.
Impact: Enables attackers to inject malicious Flash, Java, or PDF plugin objects that bypass script execution filters.
Recommended Correction: Always include `object-src 'none';` explicitly in every CSP policy.
Impact: Inadvertently breaks legitimate analytics, payment gateways, or customer widgets, causing severe site outages.
Recommended Correction: Deploy first using `Content-Security-Policy-Report-Only` for 1-2 weeks; analyze violation logs before enforcing.
What are the security implications and risks of Complete Guide to CSP (Content Security Policy)?
DOM-Based Cross-Site Scripting (DOM XSS)
OWASP Top 10 Injection / CWE-79Vulnerability: Application passes untrusted input into execution sinks like `eval()`, `setTimeout(string)`, or `new Function()`.
Base Tag Hijacking (Base-URI Manipulation)
CWE-444 Inconsistent InterpretationVulnerability: Attacker injects `<base href="https://attacker.com">`, forcing all relative script URLs to load from the attacker’s domain.
How do you troubleshoot and fix errors with Complete Guide to CSP (Content Security Policy)?
Symptom: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'"
- Inline script tags (`<script>...</script>`) present in HTML without nonce or hash
- HTML event handlers (`onclick="..."`) used in markup
Symptom: Refused to connect to "https://analytics.vendor.com" because it violates directive: "default-src 'self'"
- `connect-src` is missing from CSP and fell back to `default-src 'self'`
Frequently Asked Questions About Complete Guide to CSP (Content Security Policy)
Q:What is the difference between CSP Nonce and CSP Hash?
Nonces require a dynamic backend server (Node, Go, Python) to generate fresh random values on each page load. Static sites (JAMstack, Astro static builds) use SHA-256 hashes (`'sha256-xyz'`) calculated from the script contents.
Q:Does Content Security Policy completely eliminate XSS?
CSP cannot prevent logic flaws or server-side template injection before HTML generation, but it stops the attacker’s payload from executing in the browser or contacting outside command-and-control servers.
Hands-On Client-Side Tools
Test and experiment with these concepts directly in your browser. 100% private, zero server telemetry.
Technical Glossary
References & Primary Sources
Every source below directly substantiates technical statements and protocol behaviors explained in Complete Guide to CSP (Content Security Policy). Curious-Techie prioritizes official Internet standards (IETF RFCs, W3C Recommendations, WHATWG specifications) and established security bodies (OWASP, NIST). Zero sponsored or secondary links.
- [1]W3CPrimary SpecificationW3C CSP Level 3 • Section 2 & 3Verified Primary SourceTechnical Claim Supported:
Normative specification for Content-Security-Policy HTTP headers, directive fallback inheritance from default-src, and cryptographic nonce/hash-based script execution.
“A server can specify a policy for a resource that the user agent will enforce, restricting the execution of scripts, stylesheets, and embedded frames.”Source URI: https://www.w3.org/TR/CSP3/ - [2]OWASPAuthoritative Security StandardOWASP Cheat Sheet Series • Strict CSP & XSS MitigationVerified Primary SourceTechnical Claim Supported:
Authoritative security guide for strict CSP deployment using per-request cryptographic nonces and strict-dynamic to neutralize Reflected and Stored XSS.
- [3]MDNDeveloper Authority (MDN)MDN Web Docs • CSP Directives ReferenceVerified Primary SourceTechnical Claim Supported:
Reference documentation for browser implementation of CSP directives including script-src, frame-ancestors, object-src, and report-to.
Related Technical Ecosystem & Next Steps
Related Developer Tools
Related Technical Articles
Related Questions
Developer References & Specifications
Continue Learning
Content Security Policy (CSP) Hands-On Lab
Step into the interactive lab to defend a vulnerable DOM application with strict CSP nonces.