Understanding Content Security Policy: A Pentester’s Guide
Skip to main content CSP for Pentesters: Understanding the Fundamentals 8 min read October 19, 2025 Site Updates 💬 Comments Available Drop your thoughts in the comments below! Found a bug or have feedback? Let me know. 🚧 Recent Migration Migrated from Ghost to Astro. Spot any formatting issues? Report them! Email X Mastodon Table of contents Contents Hi everyone, A few weeks ago I was knee-deep in a CTF challenge.Found an XSS vulnerability, felt good about it, crafted my payload, and… nothing. The page just sat there, mocking me. Turns out the CSP was configured in this very specific way that blocked everything I tried. Spent the next hour actually reading the policy line by line, understanding what was allowed and what wasn’t. Eventually got it, but man, it made me realize how little attention I’d been paying to this header. So that’s what sparked this newsletter.I want to break down how CSP actually works and, more importantly, where people screw it up. Quick side note: I’m also working on improving the website right now. Adding a white theme because apparently some of you don’t live in dark mode like civilized people, plus keybindings and a bunch of other stuff. Should be ready soon 😄 What CSP Actually Is Picture this: you’re running a nightclub. You don’t want random people wandering in off the street, so you hire a bouncer.That bouncer has a list, and if you’re not on it, you’re not getting in. CSP is essentially that bouncer, but for your browser. The server sends a policy to the browser saying “hey, only execute scripts from these specific places I trust.” When you try to inject malicious code from somewhere else, the browser goes “nope, not on the list” and blocks it. In theory, it’s brilliant. In practice, well, that’s why we’re here.Here’s what the flow looks like: Server: “Content-Security-Policy: script-src ‘self'” You: Browser: *blocked* Console: “CSP violation: refused to load.” The problem is that configuring this correctly is way harder than it sounds. One wrong directive and the whole thing falls apart. How It Actually Works CSP operates through directives. Think of them as individual rules in that bouncer’s handbook. Each directive controls a different type of resource.Content-Security-Policy: script-src ‘self’ https://trusted.com; style-src ‘self’ This tells the browser: “Scripts can come from our domain or trusted.com. CSS can only come from our domain.” Pretty straightforward, right? But here’s where it gets interesting. If you don’t specify a directive, it falls back to default-src if that exists. And if default-src doesn’t exist either? No restriction at all. That’s the first place things start to break.The Directives That Matter Let me walk you through the ones you’ll actually care about as a pentester. script-src is your main target. This controls what JavaScript can execute. If you can bypass this, you win. Simple as that. Everything else is just noise compared to getting code execution. default-src acts as the fallback. Here’s something that trips people up constantly: if you see default-src ‘self’ and nothing else, that means EVERY type of resource uses ‘self’.Scripts, images, styles, everything. It’s more restrictive than it looks at first glance. object-src controls those old-school tags like
Andrii Bidochko
CTO UBOS
Andrii Bidochko is an AI entrepreneur and researcher focused on AI agents, reinforcement learning, and autonomous systems. He writes about the technologies shaping the future of machine intelligence, from frontier models and agent architectures to real-world AI applications.
Sign up for our newsletter
Stay up to date with the roadmap progress, announcements and exclusive discounts feel free to sign up with your email.