How to Implement Modern Content Security Policy (CSP) Headers in Custom Web Frameworks: A Beginner's Step-by-Step Guide
A Content Security Policy (CSP) is an HTTP header that prevents Cross-Site Scripting (XSS) and data injection attacks by restricting which scripts, styles, and resources a browser can execute. In a custom web framework, implementing modern CSP requires generating unique, per-request cryptographic tokens (nonces) and injecting them into your HTTP response pipeline.
Step 1: Adopt a Strict CSP Policy
Avoid outdated origin allowlists (which frequently suffer from domain bypasses) and adopt a modern, nonce-based strict policy.
| Directive | Recommended Value | Security Purpose |
default-src | 'self' | Fallback limit for unspecified directives. |
script-src | 'nonce-{RANDOM}' 'strict-dynamic' | Executes scripts matching the per-request nonce and allows them to dynamically load child scripts. |
object-src | 'none' | Blocks legacy plugin embeds like Flash or Java Applets. |
base-uri | 'none' | Disables <base> tag manipulation that could alter relative URLs. |
frame-ancestors | 'none' | Prevents clickjacking by blocking embedding inside <iframe> tags. |
Step 2: Create a Request-Scoped Nonce Generator
A nonce must be cryptographically random and unique for every single HTTP request. Generate a 128-bit (16-byte) random byte array encoded in base64 before processing HTML views.
- Node.js / Express Example:
JavaScript
- PHP Example:
PHP
Step 3: Build the Framework HTTP Middleware
Hook the header creation into your framework's request/response lifecycle using a middleware pattern. This creates the nonce, attaches it to the request context for templating, and appends the Content-Security-Policy header to the response.
JavaScript
Step 4: Attach Nonces to HTML Script Tags
Pass the generated nonce down into your framework's view engine or layout renderer. Any <script> tag lacking a matching nonce attribute will be blocked automatically by the browser.
HTML
Step 5: Test with Report-Only Mode First
Before turning on strict enforcement in production, deploy the policy using Content-Security-Policy-Report-Only. This outputs violation warnings to the browser developer console and logs them to a target endpoint without breaking site functionality.
HTTP
Once all legitimate third-party tags and inline scripts contain valid nonces and throw zero console errors, switch the header name back to Content-Security-Policy to lock down your web application.