HeoLab
ToolsBlogAboutContact
HeoLab

Free developer tools with AI enhancement. Built for developers who ship.

Tools

  • JSON Formatter
  • JWT Decoder
  • Base64 Encoder
  • Timestamp Converter
  • Regex Tester
  • All Tools →

Resources

  • Blog
  • What is JSON?
  • JWT Deep Dive
  • Base64 Explained

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 HeoLab. All rights reserved.

Tools work in your browser. Zero data retention.

HomeBlogContent Security Policy (CSP): A Practical Guide for Developers
Table of Contents▾
  • What Is a Content Security Policy?
  • The Core Directives
  • Common Source Values
  • A Real-World Policy for a Next.js App
  • The Nonce Pattern (Recommended)
  • Start in Report-Only Mode
  • Step-by-Step Implementation
  • Testing Your Policy
security#csp#security#xss

Content Security Policy (CSP): A Practical Guide for Developers

Learn how to implement CSP headers to protect your web app from XSS attacks, with real-world examples and a step-by-step policy builder.

Trong Ngo
February 23, 2026
3 min read

Cross-Site Scripting (XSS) is consistently in the OWASP Top 10. Content Security Policy (CSP) is the most effective browser-level defense — it tells the browser exactly which resources are allowed to load. This guide explains how to implement it without breaking your app.

What Is a Content Security Policy?

CSP is an HTTP response header that instructs browsers to block or allow resources based on rules you define. A script from an unauthorized origin? Blocked. An inline <script> tag injected by an attacker? Blocked.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'

The Core Directives

DirectiveControls
default-srcFallback for all resource types not explicitly listed
script-srcJavaScript sources (most important)
style-srcCSS sources
img-srcImage sources
connect-srcXHR, fetch, WebSocket connections
font-srcWeb fonts
frame-src<iframe> sources
form-actionWhere forms can submit
base-uriRestricts <base> tag URLs
upgrade-insecure-requestsUpgrades HTTP to HTTPS automatically

Common Source Values

'none'           — Block everything for this directive
'self'           — Same origin only
'unsafe-inline'  — Allow inline scripts/styles (weakens CSP)
'unsafe-eval'    — Allow eval() (avoid if possible)
https://cdn.example.com — Specific domain
https:           — Any HTTPS URL
'nonce-{base64}' — Allow specific inline scripts with matching nonce
'sha256-{hash}'  — Allow specific inline scripts by hash

A Real-World Policy for a Next.js App

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{RANDOM_NONCE}' https://www.googletagmanager.com;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  font-src 'self' https://fonts.gstatic.com;
  img-src 'self' data: https:;
  connect-src 'self' https://api.yourapp.com https://vitals.vercel-insights.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';

The Nonce Pattern (Recommended)

Nonces let you allow specific inline scripts without 'unsafe-inline'. Generate a new random nonce on every request:

// Next.js middleware
import { NextResponse } from 'next/server';
import crypto from 'crypto';

export function middleware(request) {
  const nonce = crypto.randomBytes(16).toString('base64');
  const csp = `
    default-src 'self';
    script-src 'self' 'nonce-${nonce}';
    style-src 'self' 'unsafe-inline';
  `.replace(/\s+/g, ' ').trim();

  const response = NextResponse.next();
  response.headers.set('Content-Security-Policy', csp);
  response.headers.set('x-nonce', nonce); // pass to RSC
  return response;
}
// Use nonce on inline scripts in layout.tsx
<Script nonce={nonce} src="https://www.googletagmanager.com/gtag/js" />

Start in Report-Only Mode

Before enforcing, use Content-Security-Policy-Report-Only to detect violations without breaking anything:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /api/csp-report

This logs violations to your endpoint so you can fine-tune the policy before switching to enforcement.

Step-by-Step Implementation

  1. Start with report-only — observe violations for 1–2 weeks
  2. Add directives one by one — start with default-src 'self'
  3. Identify broken resources — check browser console for CSP errors
  4. Whitelist legitimate sources — add only what you actually use
  5. Switch to enforcement — move from Report-Only to Content-Security-Policy
  6. Never use 'unsafe-inline' for scripts — use nonces or hashes instead

Testing Your Policy

Use the CSP Builder tool to visually construct and preview your policy, then test it with Google's CSP Evaluator.

A strict CSP is one of the highest-impact security improvements you can add to a web app with minimal user-visible change.

Try These Tools

Content Security Policy Builder

Build a Content-Security-Policy header interactively. Checkbox UI for directives and sources.

Related Articles

Understanding OAuth 2.0 and OpenID Connect: A Developer's Guide

3 min read

The Developer's Guide to Password Security

4 min read

How to Implement TOTP Two-Factor Authentication in Your App

3 min read

Back to Blog

Table of Contents

  • What Is a Content Security Policy?
  • The Core Directives
  • Common Source Values
  • A Real-World Policy for a Next.js App
  • The Nonce Pattern (Recommended)
  • Start in Report-Only Mode
  • Step-by-Step Implementation
  • Testing Your Policy

Related Articles

Understanding OAuth 2.0 and OpenID Connect: A Developer's Guide

3 min read

The Developer's Guide to Password Security

4 min read

How to Implement TOTP Two-Factor Authentication in Your App

3 min read