Home > Blog

How Content Security Policy (CSP) Works: A Basic (and Dramatic) Explanation

Return to full Blog

Content Security Policy (CSP) is a browser security mechanism with the potential to significantly mitigate XSS and content injection attacks when properly implemented on websites. This article will focus on a basic explanation of what CSP is and conceptually how it works. It is not an implementation guide.

Adopted at a Snail's Pace

I'd say that CSP is relatively new, but it's actually been around since at least 2011, when Mike West also referred to them as "relatively new" in his article "Content Security Policy: A Primer". The W3C issued its first public draft of Content Security Policy 1.1 in December of 2012 (they are now working on CSP Level 2). That's, like, 18 years in cat years.

CSP still seems fairly new, however, because it just hasn't gained that much traction or attention as of yet. I'll speak more to that issue in my next article on the subject of CSP. In the mean time, here's a review of how CSP is supposed to work.

You Might Feel a Slight Pinch

Okay, so the idea is this: certain types of attacks including Cross Site Scripting (XSS) and some data injection attacks usually rely on the execution of malicious code injected into a webpage loaded into a browser – code that then manages to find its way back to the web server where it can mount the real attack.

Malicious code can be inserted into a number of different types of page content resources. Examples of page resources commonly used for XSS and injection attacks are inline and external javascripts and CSS, framed content, external font files, external data files, and even tainted image files, among others.

An attacker may be able to get their foot into the door of your web application if they can manage to get the browser to load and execute a compromised resource on one of your pages. It's kind of like the villain injecting the hero with truth serum to extract the secrets needed to take over the realm and impose their villainous chaos.

The Source of all Your Troubles

Every web page resource originates from somewhere, right? That "somewhere" is known as the "source".

The source of most types of external resources is defined via the "src" attribute in an HTML tag that represents a request for a resource to be loaded. For the purposes of CSP, the term "inline" is considered to be the "source" of inline scripts, styles, images, etc. Makes sense.

Until the introduction of CSP and a few other security-related headers, browsers generally didn't give a rip about what kind of resource they were loading or where it came from – the browser simply loaded and evaluated whatever resource it was told to load and evaluate – notwithstanding browser settings and extensions within the control of the user, such as pop-up blockers, which are designed to protect the end user from the web site, and developer extensions, which allow developers to fiddle with a loaded page. It's still the wild wild west out there on the web.

"Hey, Browser! Here is My Content Security Policy. Enforce It!"

Ah, but what if a web site/application could compel the browser to enforce a set of rules – a "policy" – that places restrictions on which types of content resources are allowed as well as the sources from which they may originate, protecting the web application from the end user and restoring some order to the realm? Imagine this:

"Firefox, I command thee to allow external javascript files, but only from my own domain and Google Analytics' domain (since they are good guys, right?), and I say off with the heads of inline javascript and all other external javascript files you may be asked to load while working with this page!" Sounds a bit dramatic (especially when read aloud in my theater stage voice), but that really is how a Content Security Policy works: the policy lays down the law with regards to content resources, and the deputized browser is honor-bound to enforce that law.

The Good, the Bad, and the CSP Headers

Obviously, such a policy would need to allow the law-abiding citizens of your page's content: the legitimate scripts, fonts, styles, etc. that are needed to make the page work.

To allow the "good" resources and arrest the "bad" resources, the CSP 1.1 specification defines a "policy language", which includes a set of 18 "policy directives" that can be issued from the web application to the browser in the form of HTTP headers called Content Security Policy headers, or CSP headers for short.

According to the specification, most headers are used to declare which sources and uses are acceptable for a given type of resource (a policy directive), and all non-listed sources and unacceptable uses are to be blocked by the browser.

For example, one key directive is the script-src directive, which allows you to define a whitelist of sources for scripts that can be loaded/executed within the web page, if any at all. As an example, such a whitelist might include 'self', which allows external scripts from the web application's own domain, and it might also include *.facebook.com, which allows external scripts from any subdomain (* is a wildcard) at facebook.com. With this script-src policy directive declared, any attempts by a hacker to get the browser to executive a bit of injected inline javascript or an external javascript file from another domain source would be blocked by the browser.

There's a little more to it than that, of course, but that's the main gist. Awesome magic sauce, right?

Not So Fast Stranger

The good news is that all of the major browsers are on board with (mostly) compatible CSP implementations these days, (in particular, Mozilla has been ahead of the pack most of the way and has a lot of great information about CSP on their site), and you can issue CSP headers from your web application fairly easily, which is why I began by saying that CSP has the potential to significantly mitigate injection and XSS attacks.

The bad news, however, is that applying restrictions and writing effective laws that always exonerate the innocent and arrest the guilty is a very tricky task. For example, to declare that no inline scripts are allowed, your web application cannot rely on any inline scripts, but allowing inline scripts leaves your application open to some of the most common attacks. (Technically, there is a way around this that uses nonces to sandbox legitimate inline scripts, but integration is further complicated.)

Nice Security, If You Can Get It

In conclusion, if you can implement CSP into your web site with an effective set of policy declarations, you can significantly reduce the likelihood XSS and content injection attacks, but there are many obstacles to achieving such an implementation in the real world – a topic I will cover in depth in my next article: Content Security Policy (CSP): Awesome Sauce in Theory, Rotten Potatoes in the Real World.

Comments (0)    [ view/post comments ]