🛡️ Content Security Policy (CSP): A Complete Guide for Developers

Security is one of the most critical aspects of modern web development. Even if your code is correct, attackers may exploit vulnerabilities like Cross-Site Scripting (XSS) or Clickjacking. That’s where Content Security Policy (CSP) comes in.

This blog…


This content originally appeared on DEV Community and was authored by Fazal Mansuri

Security is one of the most critical aspects of modern web development. Even if your code is correct, attackers may exploit vulnerabilities like Cross-Site Scripting (XSS) or Clickjacking. That’s where Content Security Policy (CSP) comes in.

This blog covers:
✅ What CSP is & how it works
✅ All major directives (default-src, script-src, img-src, etc.) explained in detail
✅ Real-world examples
✅ Best practices & common pitfalls

Let’s dive in. 🔥

⚙️ What is CSP & Why Do We Need It?

  • Content Security Policy (CSP) is an HTTP response header that defines where browsers can load resources (scripts, images, styles, fonts, iframes, workers, etc.) from.
  • Its main purpose: prevent XSS attacks by restricting execution of malicious scripts.
  • Without CSP, if an attacker injects a script into your page, the browser executes it blindly. With CSP, you can whitelist only trusted domains, blocking everything else.

Example CSP header:

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

This means:

  • By default, only load resources from the same origin ('self').
  • Allow images from cdn.example.com.
  • Allow scripts from self and Google APIs.

⚠️ Important:
If default-src is missing, everything is allowed, weakening your CSP.

📌 Important Directives

Here’s a breakdown of commonly used CSP directives:

🔑 default-src

The fallback for all other directives (if they are not explicitly defined).

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

If script-src or style-src is missing, browsers fall back to default-src. ✅

📜 script-src

Defines where JavaScript can be loaded from.

Content-Security-Policy: script-src 'self' https://apis.google.com;
  • Special values:

    • 'self': allow only current domain
    • 'unsafe-eval': allow eval() usage (⚠️ dangerous)
    • 'unsafe-inline': allow inline scripts (⚠️ not recommended)
  • Better options:

    • Nonce → Random value per request:
    <script nonce="abc123">console.log("Safe!");</script>
    

    With CSP:

    Content-Security-Policy: script-src 'self' 'nonce-abc123';
    
    • Hash → Allow only exact inline script:
    <script>alert("hello")</script>
    

    With CSP:

    Content-Security-Policy: script-src 'self' 'sha256-XYZhashHere...';
    

✅ Nonce & Hash are safer than 'unsafe-inline'.

🎨 style-src

Controls where CSS can be loaded from.

Content-Security-Policy: style-src 'self' https://fonts.googleapis.com;

⚠️ Using 'unsafe-inline' allows inline styles → risky.
🔑 Instead:

  • Use nonce or hashes for dynamic styles.
  • Example:
  <style nonce="abc123">.btn { color: red; }</style>

🖼️ img-src

Defines allowed image sources.

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

👉 data: allows base64-encoded images.

📄 font-src

Controls allowed font sources.

Content-Security-Policy: font-src 'self' https://fonts.gstatic.com;

🔗 connect-src

Defines where AJAX/fetch/WebSocket connections can be made.

Content-Security-Policy: connect-src 'self' https://api.example.com;

🎵 media-src

Specifies allowed sources for <audio> and <video>.

Content-Security-Policy: media-src 'self' https://media.example.com;

🏗️ frame-src vs frame-ancestors

  • frame-src: Controls what your app can embed in an <iframe>.
  Content-Security-Policy: frame-src https://www.youtube.com;
  • frame-ancestors: Controls who can embed your site.
  Content-Security-Policy: frame-ancestors 'none';

✅ Use frame-ancestors to prevent clickjacking.

🧩 worker-src

Defines allowed sources for Web Workers & Service Workers.

  • Web Workers: Run scripts in a separate thread (background tasks).
  • Service Workers: Proxy requests for offline support / caching.
Content-Security-Policy: worker-src 'self' https://cdn.example.com;

📂 object-src

Restricts plugins like Flash/Silverlight (legacy). Best to set 'none'.

Content-Security-Policy: object-src 'none';

📝 Reporting with CSP

Instead of enforcing, you can test with reporting only:

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

This way, violations are logged but not blocked. Useful before rollout.

💡 Real-World Example

Imagine your webapp loads:

  • Scripts from your domain + Google APIs
  • Styles from your domain + Google Fonts
  • Images from CDN

CSP could look like:

Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://cdn.example.com; connect-src 'self' https://api.myapp.com; object-src 'none'; frame-ancestors 'none'

This protects you from attackers injecting malicious scripts/images from untrusted domains.

🚨 Common CSP Issues Developers Face

  • ❌ Images not loading → Forgot img-src domain.
  • ❌ Fonts breaking → Missing font-src.
  • ❌ Videos not playing → media-src missing.
  • ❌ API calls failing → Missing connect-src.
  • ❌ App not embeddable → Strict frame-ancestors.

👉 If your frontend/backend look fine but still break, check CSP first.

✅ Best Practices

  • Always define a strict default-src.
  • Avoid 'unsafe-inline' and 'unsafe-eval' unless absolutely necessary – use nonces or hashes.
  • Use 'self' wherever possible.
  • Test with Content-Security-Policy-Report-Only before enforcing.

📌 Conclusion

CSP is not just another header—it’s a powerful security shield 🛡️ for your apps.
The right configuration prevents XSS, clickjacking, and data injection while keeping performance intact.

👉 The bottom line: CSP = Control + Security + Peace of Mind.


This content originally appeared on DEV Community and was authored by Fazal Mansuri


Print Share Comment Cite Upload Translate Updates
APA

Fazal Mansuri | Sciencx (2025-08-30T11:00:57+00:00) 🛡️ Content Security Policy (CSP): A Complete Guide for Developers. Retrieved from https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/

MLA
" » 🛡️ Content Security Policy (CSP): A Complete Guide for Developers." Fazal Mansuri | Sciencx - Saturday August 30, 2025, https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/
HARVARD
Fazal Mansuri | Sciencx Saturday August 30, 2025 » 🛡️ Content Security Policy (CSP): A Complete Guide for Developers., viewed ,<https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/>
VANCOUVER
Fazal Mansuri | Sciencx - » 🛡️ Content Security Policy (CSP): A Complete Guide for Developers. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/
CHICAGO
" » 🛡️ Content Security Policy (CSP): A Complete Guide for Developers." Fazal Mansuri | Sciencx - Accessed . https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/
IEEE
" » 🛡️ Content Security Policy (CSP): A Complete Guide for Developers." Fazal Mansuri | Sciencx [Online]. Available: https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/. [Accessed: ]
rf:citation
» 🛡️ Content Security Policy (CSP): A Complete Guide for Developers | Fazal Mansuri | Sciencx | https://www.scien.cx/2025/08/30/%f0%9f%9b%a1%ef%b8%8f-content-security-policy-csp-a-complete-guide-for-developers/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.