Active content on websites (i.e. JavaS­cript, CSS, ActiveX) can be a security risk for internet users and website operators since they can be ma­nip­u­lated by cross-site scripting. The Content Security Policy (CSP) was in­tro­duced to ensure that internet sites could be used to their full extent without having to worry about any security risks. The security standard is designed to protect against malicious attacks and is now supported by most web browsers. The security concept protects both websites and internet users. But what is behind it and how does CSP work?

De­vel­op­ment of the Content Security Policy

The Content Security Policy dates back to 2004 when it was still known as 'Content Re­stric­tion'. The reason for this effort was an in­creas­ing number of vul­ner­ab­il­it­ies in internet scripts. Cross-site scripting (XSS) is a criminal method of in­filt­rat­ing malicious code into a website, and poses a major risk for users. Users access a trust­worthy website, but there is a script running that loads malicious data from an external source. Cyber criminals often make use of security vul­ner­ab­il­it­ies in the website’s com­ment­ary functions. By doing this, they can gain access to personal computers without internet users knowing it. Website operators won’t even notice that strange code has been in­tro­duced.

To solve this problem, the Mozilla Found­a­tion promoted the de­vel­op­ment of the CSP. The advantage behind the security standard is that rules can be set up in the browser to tell the software which scripts it is allowed to load and which it isn’t. To do this, the Content Security Policy uses HTTP headers.

Fact

The Mozilla Found­a­tion is behind the de­vel­op­ment of the Firefox browser. The non-profit or­gan­isa­tion is re­spons­ible for the ori­ent­a­tion of Mozilla’s projects and in­nov­a­tions to do with the internet. The Found­a­tion was founded by former Netscape employees, who developed one of the first web browsers.

How does the Content Security Policy work?

When com­mu­nic­at­ing online, clients and server exchange data via the Hypertext Transfer Protocol (HTTP). HTTP header fields are an important part of the requests and responses: para­met­ers and arguments are trans­ferred in these, which are important for ex­chan­ging in­form­a­tion between the two call par­ti­cipants (server and client). They are generally divided into inquiry and response fields, and can contain in­form­a­tion such as character set, language, and cookies. CSP is im­ple­men­ted as a response header field. This means that the server delivers the in­form­a­tion and the browser processes it. The Content Security Policy header is created by the website operator and inserted on every subpage of the website where you want the security standard to be applied. As the operator of the website, you have the pos­sib­il­ity of defining different security pre­cau­tions for each in­di­vidu­al page. You can implement the security concept more easily by creating .htaccess files, which are located in the same (or hier­arch­ic­ally higher) folders as the cor­res­pond­ing web pages, or by embedding CSP directly into the server con­fig­ur­a­tion.

Note

If you want to check whether your browser supports the Content Security Policy, you can use the CSP browser test. This test attempts to load scripts and images from unknown (harmless) sources and tells you if this was suc­cess­ful.

In terms of the Content Security Policy and pre­vent­ing cross-site scripting, website operators should store all scripts in separate files instead of embedding them directly in the website’s source code. The CSP then works in a similar way to a whitelist: in the header, the sources, from which scripts and data can be loaded, are named. If an unknown script has slid un­detec­ted into the HTML code of the page and is now trying to load external data, the user’s browser needs to prohibit this. By default, the CSP blocks all scripts that can be found directly in the code (inline scripts). This protects both the website and the internet user as well as any sensitive data. Cross-site scripting is re­l­at­ively easy for cyber criminals to ma­nip­u­late. Almost every website has an input field i.e. comment function, search bar, or log-in field. Instead of simple text, it’s possible to also enter scripts. If the server is not ad­equately secured, criminals can implement phishing in­ter­faces, bringing the entire website to a stand­still or gaining control of the user’s web browser using malicious software. CSP (or to be more precise: the cor­res­pond­ing header field) tells the web browser which sources it is permitted to load data from. If the policy is im­ple­men­ted in the website’s code, at­tempt­ing to retrieve XSS-im­ple­men­ted code will be met with an error message. The Content Security Policy also enables website operators to change many other settings. This can be done through these dir­ect­ives:

  • base-uri: Restricts the URLs, which can be used in a website’s <base> element
  • child-src: Defines valid sources for web workers and nested browsing contexts loaded using elements such as <frame> and <iframe>
  • connect-src: Limits the sources that the site can connect to i.e. links
  • font-src: Defines valid font sources
  • form-action: Defines valid sources that can be used as an HTML <form> action
  • frame-ancestors: Defines valid sources for embedding the resource using <frame> and <iframes>
  • img-src: Defines valid images sources
  • media-src: Defines valid audio and video sources
  • object-src: Defines valid plugin sources
  • plugin-types: Defines valid plugins types
  • report-uri: Lets the browser know when a URL (to which reports are sent) violates security measures
  • script-src: Defines valid JavaS­cript sources
  • style-src: Defines valid stylesheet sources
  • upgrade-insecure-requests: Specifies that unsafe HTTP sites should be treated like HTTPS sites
  • sandbox: Moves the site in question to a sandbox where forms, pop-ups, and scripts are forbidden

These dir­ect­ives only apply if they are ex­pli­citly set. Otherwise, they are open by default and therefore pose a security risk. However, this can be changed using default-src: you can set the default state of all dir­ect­ives ending with -src. For example, instead of leaving it open, you can specify that only data from your own website may be loaded unless you have specified otherwise in the HTTP header of the in­di­vidu­al web page. In separate dir­ect­ives, you add ad­di­tion­al sources. You can enter any number of dir­ect­ives into the header field. If you want to include several dir­ect­ives, separate them with semi­colons. In addition, you as the website operator must specify all sources within a directive. Multiple entries of the same directive with ad­di­tion­al sources are not permitted (such as in the following example):

script-src example1.local; script-src example2.local

In this case, only the first source is relevant, the second one is ignored by the client. Instead, you must record both sources in one directive:

script-src example1.local example2.local

If you do not need certain types of content for a page or the entire website, you can enter the value 'none' in the header – so you can specify that no sources may be loaded at all. You can also use the value 'self' – this means that the browser can only load content from the same source. Both values must always be quoted in single quotation marks, otherwise none and self will be in­ter­preted as domains. There are different header options for defining a Content Security Policy:

  • Content-Security-Policy
  • X-Webkit-CSP
  • X-Content-Security-Policy

Not all browsers support every term. However, the W3C (the body re­spons­ible for defining web standards) suggests Content Security Policy. Therefore, all modern browsers have adapted to this security standard in the meantime (the other two versions are con­sidered obsolete). To make sure that you reach as many internet users as possible (even those with out-of-date browsers) with your CSP, it is advisable to include all header fields. If a cor­res­pond­ing web browser can’t handle the Content Security Policy header, it will simply ignore it and display the website without any problems – however, ad­di­tion­al pro­tec­tion isn’t given to the affected users. Usually, you will set HTTP headers across your entire domain. For sub-dir­ect­or­ies, you can use the .htaccess file. You then use the CSP security standard to set special rules for in­di­vidu­al subpages. For example, if you have im­ple­men­ted a social media button on one page, but not on the next one, it makes sense to only allow access to the external source on the first page. Sources can be entered as addresses, in their own way or as wildcards. The following entries are therefore allowed:

  • script-src example.com:443 – scripts are only allowed from this domain via HTTPS
  • script-src 'none' – scripts aren’t allowed to be loaded
  • script-src 'self' – scripts may be loaded from the same source as the current page, but not from sub­do­mains
  • script-src https: – scripts can be loaded from any domain as long as it starts with HTTPS
  • script-src example.com – scripts may be loaded from this domain
  • script-src *.example.com – scripts from this domain and all sub­do­mains are allowed
  • img-src data: – images can be loaded via data URLs

A Content Security Policy basically stip­u­lates that scripts may only be loaded from files, not directly from the website code. If you want to bypass this, you can use the command script-src 'unsafe-inline'. However, you should be aware that you are weakening security. The safety standard also prohibits the eval () feature. This command can be used to convert text into JavaS­cript code – but this can also pose a security risk. If you still need this function, you can re­act­iv­ate it with script-src 'unsafe-eval'.

Tip

you can secure unsafe-inline using a detour. Hash values or nonce source close this vul­ner­ab­il­ity as much as possible.

If scripts are no longer allowed to appear directly in the code, you must create a separate file for each script. The script’s function is stored in a .js File. The website’s code only refers to these:

<script src='example.js'></script>

What the script does in the end is described in the example.js. You must also store style elements in separate stylesheets. If you want to implement an internet security policy as a website operator, it is not enough to simply insert the header. You also need to check and customise your website’s source code.

Note

do you want to know how secure your own website is? Mozilla has provided an easy-to-use test: Ob­ser­vat­ory by Mozilla scans your website and gives you a grade after it’s completed, and tells you how to make your site safer

Content Security Policy: an example

As an example, we now show you how to implement a Content Security Policy header and explain what can be achieved with it.

  • Content-Security-Policy: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' fonts.google.com/; report-uri example.org/report.html"
  • X-Content-Security-Policy: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' fonts.google.com/; report-uri example.org/report.html"
  • X-WebKit-CSP: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' fonts.google.com/; report-uri example.org"

You can see that every CSP variant appears in the header so that as many different browsers as possible can be addressed. Inside each header name, the content is identical: sources are listed one after the other, and the dir­ect­ives are separated by a semicolon. The syntax is always the same. In fact, only the name of the field changes, so you can easily duplicate the content.

First, we determine that, unless otherwise specified in a directive, data should not be loaded from just any source (default-src). This makes things a little bit safer. You should always define default-src first. This will prevent a po­ten­tially forgotten directive from leaving a gap in your Content Security Policy.

Next, we define the source from which scripts can be loaded (script-src). In the example, we determine that the browser only loads scripts from the same source and from example.com including all sub­do­mains (you assign the wildcard using *). Fur­ther­more, we determine that clients are only allowed to load stylesheets from their own sources (style-src). Images are only allowed from their own source as a data URL (img-src). According to our Content Security Policy header, fonts may only be down­loaded from Google’s own sources. In the example, we specify a location to which no­ti­fic­a­tions are sent if someone attempts to violate the security standard (report-uri).

You might have noticed that we haven’t included all the dir­ect­ives in the header. This doesn’t cause any problems: In this case, we don’t need any more whitel­ists, and the default src turns off all other sources.

Tipp

several Content Security Policy gen­er­at­ors are available on the internet. With offers such as CSP Is Awesome or Report URI, you can create CSP header fields easily and reliably.

Go to Main Menu