Building more secure web apps with ‘Content Security Policy’

Embedding third-party content is an important feature for modern websites. How can abuse be prevented in a technically elegant way without restricting the user too much?
Created with Lunacy

Building more secure web apps with ‘Content Security Policy’

by Simon Olofsson

Modern web apps use content from many different sources. Fonts from Google, JavaScript and CSS from various CDNs and so on. While this is not a problem on its own, it becomes challenging when you don’t have full control over the content that is embedded in your app.

Let’s say you’re on the mission to build world’s best website builder. In order to give your users the maximum amount of flexibility to design their new site, you allow them to insert third-party content from any site. While you implement your embed Widget, you realize, that you want to forbid JavaScript sources from third parties.

Now you could go down the hard route and try to parse the embedded content the user has entered and forbid certain input. A cumbersome and error prone undertaking. This is where Content Security Policy (CSP) steps in and helps you define the resources that are allowed to load on your site.

CSP is a HTTP response header and can be alternatively used as a HTML meta element. We’ll start with a basic example and allow only JavaScript sources from our site; these are the ones that come from the same origin as the current site. The value for the “Content-Security-Policy” header would look like this: “script-src 'self';”. Content coming from other origins won’t be loaded by the user’s web browser.

Other directives specify the allowed sources for styles, images, fonts, media, or frames. The sources can be specified with literal domain names, wildcards, nonces, or hashes. And there are even more directives and sources available. A pretty useful directive, for example, allows the specification of a report URI where violations are sent to.

A somewhat special directive is “frame-ancestors”. This specifies the valid sources from where a site can be embedded. It’s related to the “X-Frame-Options” HTTP Header but circumvents some of its shortcomings.

If you want to secure your web app and have full control over the loaded resources you should definitely dive deeper into the CSP docs. MDN provides a useful introduction at and lists all possible directives and sources with explanations and examples.