Content Security Policy

Content Security Policy (CSP) is a browser security feature that restricts which sources can load scripts, styles, images, and other resources. It helps prevent XSS, data injection, and malicious content by allowing only trusted origins defined in HTTP headers.

The formal specification is maintained by the World Wide Web Consortium.


Without CSP, a malicious script injected into your site could:

  • Steal cookies or session data
  • Redirect users to phishing pages
  • Perform actions on behalf of the user

CSP reduces this risk by blocking untrusted sources.

CSP lets a website declare:

  • Which sources of scripts, styles, images, fonts, etc. are trusted
  • Whether inline scripts or eval() are allowed
  • Where data can be sent (e.g., APIs)

This is done via an HTTP header or a <meta> tag.


# Example CSP Header

Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.example.com; img-src 'self' data:;

What this means:

  • default-src 'self' → Only load resources from the same origin
  • script-src 'self' https://apis.example.com → Scripts allowed only from your site + that API
  • img-src 'self' data: → Images can come from your site or inline base64 data


# Common Directives

  • default-src – fallback for all resource types
  • script-src – JavaScript sources
  • style-src – CSS sources
  • img-src – image sources
  • connect-src – AJAX/fetch/WebSocket endpoints
  • font-src – font sources
  • frame-src – iframes
  • object-src – plugins (often set to 'none')


# How companies actually use CSP

Most production systems don’t use strict CSP immediately because:

  • It breaks existing scripts
  • Requires audit of all external resources

Instead, teams:

  • Start with report-only mode
  • Monitor violations
  • Gradually enforce stricter policies


# Common CSP mistakes

  • Using 'unsafe-inline' which defeats CSP purpose
  • Blocking necessary third-party scripts unintentionally
  • Not testing in report-only mode first


# When CSP can be difficult

  • Legacy applications with inline scripts
  • Heavy use of third-party integrations
  • Rapid prototyping environments

# Safest universal test (recommended)

Uses a reserved domain that will never resolve:

fetch('https://example.invalid/test');

Why this is best:

  • .invalid is guaranteed non-existent
  • No real server involved
  • Still triggers CSP violation (connect-src)

# Test connect-src

fetch('https://example.invalid/api');

# Test script-src

const s = document.createElement('script');
s.src = 'https://example.invalid/script.js';
document.body.appendChild(s);

# Test img-src

const img = new Image();
img.src = 'https://example.invalid/image.png';
document.body.appendChild(img);

# Test media-src

const video = document.createElement('video');
video.src = 'https://example.invalid/video.mp4';
document.body.appendChild(video);
video.play();

# Test inline script blocking

const s = document.createElement('script');
s.innerHTML = 'console.log('inline test')';
document.body.appendChild(s);

Useful when you later remove 'unsafe-inline'

# Test frame-src

const iframe = document.createElement('iframe');
iframe.src = 'https://example.invalid';
document.body.appendChild(iframe);

# What you should verify

After running any test: Console you should see: Refused to load ...


Published Date: 3rd May 2026


Updated Date: 3rd May 2026


About the Author: Team absequ is a group of engineers and researchers working on real-world systems, software development, and technology solutions.