ssc-hrep3
ssc-hrep3

Reputation: 16069

Content Security Policy (CSP) Header: Onto each file or only the actual HTML pages?

I'm currently adding the Content Security Policy (CSP) header to our application. I'm wondering onto which files the header must be attached to. After some research, I did not find a clear answer to it.

Twitter, e.g. only added it to the actual HTML document. Facebook, however, added it to almost every resource and the HTML document (HTML, JS, CSS, etc.).

So, is it necessary to add the Content Security Policy header to each served resource file or only to the HTML document? How does it work with Ajax (JSON content) requests? How does it work with SPAs (only the index.html file or all resources)? I don't want to slow down the page by adding long CSP headers to each file if it is not necessary from a security point of view.

EDIT:

To clarify: Do browser treat images or other non-document resources differently when they come with a CSP header attached?

Upvotes: 38

Views: 17391

Answers (4)

ssc-hrep3
ssc-hrep3

Reputation: 16069

The correct answer to my question was given as an answer to another, similar question. It refers to the CSP specification which clearly states, that the policy only affects resources which create a new "execution context". This means, it is not necessary to add the CSP to REST API responses which are not meant to be opened by a browser. Please refer to the correct answer or directly to the specification of W3 which also includes a table of how different resources are handled (e.g. scripts, images, etc.).

Upvotes: 14

Martin
Martin

Reputation: 22760

CSP is not intended as a first line of defense against content injection vulnerabilities.

...

New Answer II

Question:

To clarify: Do browser treat images or other non-document resources differently when they come with a CSP header attached?

My Answer:

  • First, define 'non-document'? W3 (the guys who set how the internet actually works) have a definition of "document" and I will assume your definition is the same.

    If it is not, please clarify accordingly.

The W3 Rules on Content Security Policy (as of October 2018) state that the goals of CSP is to:

  • Mitigate the risk of content-injection attacks by giving developers fairly granular control over:

    • The resources which can be requested (and subsequently embedded or executed) on behalf of a specific Document or Worker

    • The execution of inline script

    • Dynamic code execution (via eval() and similar constructs)

    • The application of inline style

  • Mitigate the risk of attacks which require a resource to be embedded in a malicious context (the "Pixel Perfect" attack described in [TIMING], for example) by giving developers granular control over the origins which can embed a given resource.

  • Provide a policy framework which allows developers to reduce the privilege of their applications.

  • Provide a reporting mechanism which allows developers to detect flaws being exploited in the wild.

Note point 1(i);

"The resources which can be requested (and subsequently embedded or executed) on behalf of a specific Document or Worker"

The document is defined as above and a work is defined -essentially- as something that uses a JavaScript DOM model (this may be incorrect).

So the CSP is expected to apply to the documents (a given) and workers.

Are other (MP3, PDF, etc.) files documents or workers?

They are not documents, but the way they are handled in browsers does imply they are contained in a document structure.

Please see this old Chrome Bug report. Whereby a PDF failed to load contents due to the websites CSP settings and the PDF was actually being loaded by a browser plugin (native to all modern browsers) and therefore was affected by the object-src CSP.

This is CSP version 1, and I have no reason to think that either the way browsers handle non-document files or the way CSP integrates have changed significantly since that bug was filed.

Therefore: browsers are not REQUIRED to apply CSP to non-document and non-worker objects, but due to the way browsers operate they probably will apply CSP headers to non-document and non-worker objects, by fact that these objects will be wrapped in document models for ease of the browser handling files within itself.

But This is at the coding discretion of the browser and should not be expected as of October 2018.


Older Answer 2:

Question:

To clarify: Do browser treat images or other non-document resources differently when they come with a CSP header attached?

NO

CSP makes it possible for server administrators to reduce or eliminate the vectors by which XSS can occur by specifying the domains that **the browser** should consider to be valid sources of **executable scripts**. A CSP compatible browser will then **only execute scripts** loaded in **source files received from those whitelisted domains**, ignoring all other script (including inline scripts and event-handling HTML attributes).

My highlighting. Source: MDN Content Security Policy (CSP)

To explain further:

CSP works ONLY when:

  • The correct CSP HTTP headers are sent before the data content
  • The headers are received by the browser
  • The headers are understood by the browser.
  • The content (data) is received by the browser and opened within the browser.

An example of this is www.cspexample.com, On this Apache driven website the Apache httpd.conf is set with the correct CSP headers to block all scripts from google.com

The website hosts a file: https://www.cspexample.com/document.pdf; this file is somehow written to open a PDF which calls a google script to monitor keytaps on the client machine (just suppose...).

The CSP header stops this happening and blocks this script if the PDF is opened within the browser. If the PDF file is saved to the computer and then opened in the Adobe PDF file viewer, this specific CSP protection is no longer enabled. (Other mitigators may be present in the Adobe program).

When a file is downloaded to the client machine (such as saving a nefarious image file to disk), CSP does not make any protection outside of the browser.

Why does it work this way?

the CSP is a set of HTTP headers that the browser receives and are stateless. Think of HTTP as the wrapping of a parcel. Some parcels get wrapped in different things, such as fresh fruit is wrapped differently from a games console, but the wrapper never knows what's actually inside - if you send a games console wrapped as if it's fresh fruit, it would still arrive.

Following this analogy, the parcel has a sticker on it saying "WARNING" and some criteria, it's delicate, etc. Now the receiver in the postal service sees this and respects it, because that's her job. This is the browser. However the parcel can be thrown to some random person (be it a USB drive, or a disk drive or a very, very old browser) who will not read the Warning sticker and will ignore the warning - because the warning only applies to postal service workers - thus allowing the contents to connect to whatever it wants.

Old Answer 1:

You should ideally be adding the CSP at the earliest possible level, so for example in your Apache httpd.conf file, or equivalent -- and thus let it be loaded automatically every time anything is called from your website, so that it applies to every resource.

Some resources such as JPEG images can easily reference/call outside information in cretinous ways; don't trust anything simply because it looks benign. A prime (but probably harmless) example is the JPEG images used by Facebook as mentioned below (see sidenote).

re Server load: the httpd.conf info is held in server memory so there's no read/write delay etc.

Ajax is just the same as browser loads, in as far as it's simply a call to a script on the/a server.

What is or is not "necessary from a security point of view" depends entirely on what risks your system faces, what your planned mitigation of these risks outside of CSP are, and how much time and effort you want to put into trading off between fractions of micro-seconds of server load times or alternative systems.

CSP is entirely optional. If you want to micro-optimise to the point that you believe it is a tax on your user experience to use CSP, fair enough.... but you need to be aware of that choice and set up (almost certainly time consuming) alternatives, such as firewall blacklistings...

Sidenote:

Facebook resources are not always "true" resources -- it is a PHP file that loads data (say an image) and writes to a database and outputs that data as if it was JUST an image with an appropriate PHP header.

Sidenote 2:

On a PHP system (and on many others) pages and resources can be loaded and output to the end user without that user being aware that the access is passing through a codebase. For example:

<?php 

 ///
 /// Send data to a cURL request off site 
 /// 
 /// Call image from a 3rd party provider.
 ///
 /// Display image to end user as image.jpeg
 /// 

you think it's just an image, but under the hood anything could be going on.

Further, nefarious JPEG images have a long history of being able to access 3rd party resources via their meta data sets.

Upvotes: 2

IvanM
IvanM

Reputation: 3053

slow down the page by adding long CSP headers to each file

Supposedly, with 304 Not Modified status - CSP headers are not being sent
- only on initial loading

Upvotes: 0

benvc
benvc

Reputation: 15120

Browsers that support the HTTP Content Security Policy response header will prevent images (and other content) from loading for any page where the response header or a meta tag contains Content Security Policy directives that limit the domains considered as valid content sources, require all content to be loaded via HTTPS, etc. Most widely used modern browsers support Content Security Policy and apply it to control the majority of content resources (including images) associated with any HTTP request (except that web worker resource control is not supported in Safari and IE and may not be supported in Edge or Opera).

You can specifically include img-src policy directives in your Content Security Policy to restrict the domains considered as valid sources for images as well as require the HTTPS scheme, etc. There are also specific directives available for a variety of other resources including fonts, frames, media (audio, video, etc), scripts, stylesheets, web workers, etc.

You will either need to include your Content Security Policy as part of the HTTP response header that is returned from your web server as part of each HTTP request where you wish to limit valid content sources or ensure that the requested page includes a Content Security Policy meta tag like...

<meta http-equiv="Content-Security-Policy" content="default-src 'self';">

Note that IE 10+ browsers support Content Security Policy response headers but not meta tags (also there are some specific implementation details you need to attend to if you want to support IE).

Upvotes: 0

Related Questions