← Back to Blog
2026-02-263 min readby DevUtilz

Content Security Policy Guide

SecurityCSPWeb DevelopmentTutorial

Content Security Policy (CSP) Guide

CSP is your first line of defense against XSS attacks. Learn how to implement it correctly.

What is CSP?

Content Security Policy is an HTTP header that tells browsers which resources can be loaded. It prevents:

  • Cross-site scripting (XSS) attacks
  • Data injection attacks
  • Clickjacking
  • Mixed content issues

Basic CSP Header

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

This only allows resources from the same origin.

Common Directives

| Directive | Purpose | Example | |-----------|---------|---------| | default-src | Fallback for other directives | default-src 'self' | | script-src | Allowed JavaScript sources | script-src 'self' 'unsafe-inline' | | style-src | Allowed CSS sources | style-src 'self' 'unsafe-inline' | | img-src | Allowed image sources | img-src 'self' https://images.example.com | | connect-src | Allowed fetch/XHR targets | connect-src 'self' https://api.example.com | | font-src | Allowed font sources | font-src 'self' https://fonts.example.com | | frame-src | Allowed iframe sources | frame-src 'none' |

Practical Examples

Basic Security (Recommended Start)

Content-Security-Policy: 
  default-src 'self';
  script-src 'self';
  object-src 'none';

Allow External Scripts Safely

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

Google Analytics + Fonts

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://www.google-analytics.com;
  style-src 'self' https://fonts.googleapis.com;
  font-src 'self' https://fonts.gstatic.com;
  img-src 'self' https://www.google-analytics.com;

Strict Policy (Most Secure)

Content-Security-Policy:
  default-src 'none';
  script-src 'self';
  style-src 'self';
  img-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';

Implementing CSP

In Next.js (next.config.js)

module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          {
            key: 'Content-Security-Policy',
            value: "default-src 'self'; script-src 'self' 'unsafe-inline';"
          }
        ]
      }
    ];
  }
};

In Express.js

app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' 'unsafe-inline'"
  );
  next();
});

Using Meta Tag

<head>
  <meta http-equiv="Content-Security-Policy" 
        content="default-src 'self';">
</head>

Monitoring CSP Violations

Report-Only Mode (Testing)

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

Backend Handler (Node.js)

app.post('/api/csp-report', express.json(), (req, res) => {
  const violation = req.body['csp-report'];
  console.log('CSP Violation:', violation);
  // Log to monitoring service
  logger.error('CSP violation', violation);
  res.status(204).end();
});

Common Issues and Fixes

Issue: Inline Scripts Blocked

// Won't work with default-src 'self'
<button onclick="doSomething()">Click</button>

// Use instead
<button id="myButton">Click</button>

// In external JS
document.getElementById('myButton').addEventListener('click', doSomething);

Issue: Google Fonts Blocked

<!-- Add to CSP -->
font-src 'self' https://fonts.gstatic.com;
style-src 'self' https://fonts.googleapis.com;

Issue: Analytics Blocked

<!-- Add to CSP -->
script-src 'self' https://www.google-analytics.com;
img-src 'self' https://www.google-analytics.com;

Nonce-Based Inline Scripts

// Generate unique nonce
const nonce = crypto.randomBytes(16).toString('base64');

// Set header
res.setHeader('Content-Security-Policy', 
  `script-src 'self' 'nonce-${nonce}'`);

// Use in HTML
<script nonce="<%= nonce %>">
  // This script will run
</script>

Testing Your CSP

  1. Use report-only mode first
  2. Check browser console for violations
  3. Use CSP Evaluator - https://csp-evaluator.withgoogle.com
  4. Start strict, then relax as needed

Conclusion

Start with a restrictive CSP in report-only mode, monitor violations, then gradually tighten. A good CSP significantly reduces your attack surface.