.ContentSecurityPolicy

The .ContentSecurityPolicy file is used to hold Content-Security-Policy rules.

These security rules control how browsers load and connect to resources.

Purpose of Content-Security-Policy

Imagine you allow your visitors to leave comments on your web app. Those comments might (even accidentally) allow JavaScript to be embedded in the comments. This would allow an attacker to inject code that would run in the browser of all your visitors, doing anything they can do, in their names. (Hijacking their identities.)

Content-Security-Policy rules allow you to disallow this and a host of other attack vectors.

Loading Content-Security-Policy rules

Some engines automatically load Content-Security-Policy rules from .ContentSecurityPolicy files placed in specific locations while other engines require you to explicitely load them.

Maximum Content-Security-Policy rules

.ContentSecurityPolicy files also enforce the maximum level of Content-Security-Policy rules a web app may set on responses.

To rephrase, you can not allow loading resources from attacker.com without having attacker.com allowed by any one of the .ContentSecurityPolicy files within your web app.

.ContentSecurityPolicy file placement

If the engine you are using automatically loads .ContentSecurityPolicy files, place it in the desired location.

If the engine requires you to load the Content-Security-Policy rules, you can have the .ContentSecurityPolicy file anywhere within your web app, just make sure you load it.

You don’t need to set a file type on the .ContentSecurityPolicy file.

.ContentSecurityPolicy rules

You can use the simple format or the fully defined format.

You can mix and match them separated by new lines or semicolons (;).

Simple format

Just list each domain you want to allow on a new line. For example:

www.youtube.com
www.google-analytics.com

This will fully trust the source. Browsers will happily load any resource from them or otherwise communicate with them.

Valid examples:

foo.com
http://foo.com
https://foo.com
*.foo.com
http://*.foo.com
https://*.foo.com

Note that the simple format is only supported by Boomla, not browsers, thus Boomla will turn the simple format into the fully defined format before returning the response to browsers.

The simple format will allow the source for every directive of the fully defined format (see below).

Fully defined format

Use any valid Content-Security-Policy rules.

For example, the simple format rule www.youtube.com is equivalent to the fully defined rule:

default-src www.youtube.com
script-src www.youtube.com
style-src www.youtube.com
img-src www.youtube.com
connect-src www.youtube.com
font-src www.youtube.com
object-src www.youtube.com
media-src www.youtube.com
child-src www.youtube.com
form-action www.youtube.com
frame-ancestors www.youtube.com

You can also use the semicolon separated representation:

default-src www.youtube.com; script-src www.youtube.com; style-src www.youtube.com; img-src www.youtube.com; connect-src www.youtube.com; font-src www.youtube.com; object-src www.youtube.com; media-src www.youtube.com; child-src www.youtube.com; form-action www.youtube.com; frame-ancestors www.youtube.com

Valid examples:

default-src foo.com
script-src foo.com
script-src http://foo.com
script-src https://foo.com
script-src *.foo.com
script-src http://*.foo.com
script-src https://*.foo.com
script-src 'unsafe-inline'
script-src 'unsafe-eval'
style-src 'unsafe-inline'
script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='

Mixing formats

You can mix the simple and fully defined formats in a .ContentSecurityPolicy file.

Example:

www.youtube.com
script-src 'unsafe-inline'

Nonce example

A nonce can be used to allow loading a resource with the given hash. The hash is like a fingerprint for the exact content of the response, so if an attacker changes it, the browser would not load it.

This way you are not trusting an origin but the known resource.

script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='

How the browser looks up policy rules

When a browser wants to load a script or connect to another resource, it goes through the following steps:

  • select the appropriate directive, like script-src
  • find the directive in the document’s HTTP headers
  • if the directive doesn’t exist, use the default-src directive
  • apply the policy rules

Let’s look at an example for resolving directives. Given the following .ContentSecurityPolicy rules:

a.com
default-src b.com
script-src c.com
  • script-src would allow a.com and c.com, because script-src is defined and a.com uses the simple format which applies to all directives.
  • style-src would allow a.com and b.com, because style-src is NOT defined thus the fallback default-src is used, and a.com uses the simple format which applies to all directives.