Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

Subscribe to the newsletter

Get new articles and course lessons delivered to your inbox. No spam, unsubscribe anytime.

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
SecurityJune 26, 20264 min read

Content Security Policy: A Practical Guide to XSS Prevention

Content Security Policy is your strongest defense against XSS. Learn how to implement web security headers to lock down your site and stop malicious scripts.

Content Security PolicyXSSweb securitybrowser securityOWASPJavaScriptsecurity headersSecurity

During a recent refactor of a legacy dashboard, we realized our frontend was essentially a playground for potential injection attacks. We had third-party scripts scattered across the codebase, and despite our XSS prevention strategies: A guide for modern web developers, we needed a structural defense that didn't rely on perfect code. That’s when we committed to implementing a strict Content Security Policy.

Why You Need a Content Security Policy

A Content Security Policy (CSP) acts as an allow-list for your browser. Instead of hoping your code is free of vulnerabilities, you tell the browser exactly which domains are allowed to load resources like scripts, styles, and images. If an attacker manages to inject a <script> tag pointing to their malicious domain, the browser simply refuses to execute it.

When I started, I thought I could just drop a "default-src 'self'" header and call it a day. That broke roughly 60% of our production features within minutes. It’s a common mistake; you have to balance security with the realities of modern web development, where your app likely depends on CDNs, analytics, and third-party widgets.

Structuring Your CSP Headers

To implement this, you'll need to configure your server (Nginx, Apache, or your Node.js middleware) to send the Content-Security-Policy header. Don't start with a restrictive policy immediately. Instead, use Content-Security-Policy-Report-Only to log violations without breaking your site.

Here is a balanced approach for a standard web application:

DirectivePurpose
default-src 'self'Fallback for all resource types
script-src 'self' trusted-cdn.comRestricts scripts to your origin and a specific CDN
style-src 'self' fonts.googleapis.comAllows your CSS and Google Fonts
frame-ancestors 'none'Prevents clickjacking, as discussed in our Preventing Clickjacking with Modern Frame-Ancestors Policies guide

Practical Steps to Implementation

  1. Audit your current dependencies: Use the browser's Network tab to see every domain your app pulls from.
  2. Draft a loose policy: Start with script-src 'self' 'unsafe-inline' 'unsafe-eval'. Note that 'unsafe-inline' effectively disables the main benefit of CSP for XSS prevention, but it's a necessary starting point for legacy apps.
  3. Refine and tighten: One by one, remove the "unsafe" keywords. If you need to keep inline scripts, use nonces or hashes.
  4. Deploy in Report-Only mode: Send violations to a reporting endpoint. I usually use a service like report-uri or a simple internal logging endpoint to track what's getting blocked.

Dealing with Inline Scripts

The biggest hurdle is almost always inline scripts. If you have legacy code like <script>doSomething();</script>, a strict CSP will kill it. The modern way to handle this is using a CSP nonce.

When your server renders the page, generate a unique random string (the nonce) for every request. Add it to your header and your script tags:

HTTP
Content-Security-Policy: script-src 'nonce-random123'
HTML
style="color:#808080"><style="color:#4EC9B0">script nonce="random123">
  console.log("This will execute!");
style="color:#808080"></style="color:#4EC9B0">script>

This ensures that only scripts you explicitly authorized for that specific page load can run. If an attacker injects a script, they won't have the current nonce, and the browser will block it.

Common Pitfalls and Lessons Learned

I learned the hard way that third-party analytics tools are the biggest violators. They often inject their own scripts dynamically, which can be a nightmare to debug under a strict policy. If you're struggling with Preventing DOM-based XSS: A Guide for Modern JavaScript Apps, don't assume a CSP will catch everything—it's a defense-in-depth tool, not a silver bullet.

Also, be wary of the OWASP CSP guide. It’s an incredible resource, but don't copy-paste the most restrictive example if you aren't ready for it. You will break your site. Start small, monitor your reports, and tighten the screws over time.

Frequently Asked Questions

Does a CSP prevent all types of XSS? No. A CSP is a mitigation tool. It won't prevent DOM-based XSS if you are using dangerous sinks like eval() or innerHTML with unsanitized user input. You still need to write secure code.

What happens if I don't set a CSP? Your application relies entirely on the developer's ability to sanitize every single input. If there's a single injection point, the attacker can execute arbitrary JavaScript in the user's browser, steal cookies, or redirect them to malicious sites.

Should I use unsafe-inline? Only as a temporary measure. The goal of a modern CSP is to move away from inline scripts entirely, favoring external files and nonces.

I’m still experimenting with strict-dynamic, which is a newer feature that simplifies managing scripts loaded by other scripts. It’s promising, but browser support can be inconsistent depending on your user base. My advice? Don't wait for the perfect policy. Ship a report-only version today, fix the violations, and harden it next week.

Back to Blog

Similar Posts

SecurityJune 25, 20264 min read

Preventing DOM-based XSS: A Guide for Modern JavaScript Apps

Learn how to stop DOM-based XSS by securing your client-side sinks and sources. Master practical input sanitization and secure coding techniques today.

Read more
Close-up of colorful programming code displayed on a computer screen, showcasing modern coding concepts.
SecurityJune 20, 2026
4 min read

XSS prevention strategies: A guide for modern web developers

XSS prevention strategies are essential for securing modern web apps. Learn to identify the three main variants and implement robust, layered defenses today.

Read more
SecurityJune 28, 20264 min read

Preventing CSRF Attacks in Node.js: A Practical Guide

CSRF protection in Node.js is essential for web application security. Learn how to implement anti-CSRF tokens in Express to keep your users safe today.

Read more