31

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?

ssc-hrep3
  • 15,024
  • 7
  • 48
  • 87
  • Do you have user uploaded resources on your website? – Martin Jan 15 '19 at 17:39
  • @Martin, no I'm mainly protecting against malicious node modules and improper user input validation from our side. But no file resources from users are served. – ssc-hrep3 Jan 15 '19 at 17:59
  • Sorry to clarify: if any part of any data you are serving to website visitors was not written by you and is not already woidely used and easily verifiable -- then treat it as a risk and use CSP to protect users from a worst-case-scenario. – Martin Jan 15 '19 at 22:00

4 Answers4

9

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.).

ssc-hrep3
  • 15,024
  • 7
  • 48
  • 87
2

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.

Martin
  • 22,212
  • 11
  • 70
  • 132
  • 1
    That's interesting! Of course images can also be served by an intercepting server. This can be used to serve any image. But at the end, the browser receives an image with a MIME type of an image, right? And images cannot be used to connect inside the browser to another page (Ajax or anything?) So, am I assuming correctly, that anything which is viewed by the browser as a document requires CSP headers? – ssc-hrep3 Jan 15 '19 at 18:05
  • 3
    No. An innocent user (be it a node module or whatever) can upload a jpeg image that contains malicious code in its meta data. Please review the link in my answer. This is not the same as having an "intercepting" or MITM server, which should be mitigated by forcing visitors to use a TLS connection such as Lets Encrypt. – Martin Jan 15 '19 at 22:01
  • 1
    In a worst case scenario, yes, simply [viewing an image](https://thehackernews.com/2015/06/Stegosploit-malware.html) [can infect a machine](https://www.opswat.com/blog/image-borne-malware-how-viewing-image-can-infect-device). CSP is only part of the set of tools to mitigate this risk. – Martin Jan 15 '19 at 22:03
  • So, serving an image with a CSP header is treated differently by the browser than without (when it's directly called, not embedded in a document)? – ssc-hrep3 Jan 15 '19 at 22:22
  • no, serving the image with CSP prevents the image file on that server accessing / downloading 3rd party content according to the CSP rules. That [structurally] is what CSP is for. To stop unqualified access. Anyhow this is a (rare) sidepoint. – Martin Jan 16 '19 at 10:00
  • I appreciate your effort, but it still does not answer my question. It is very clear to me how the HTTP protocol works. It is also very clear to me how the backend can serve static resources and how CSP headers can be attached. Depending on the `content-type` the browser decides however how the file is rendered in the browser (as a document, as JSON data, as an image etc.) The scripts which CSP protects against are linked in a document. My question still is: What does the browser do with the CSP header if the HTTP package is not a document? Is it just ignored? – ssc-hrep3 Jan 19 '19 at 02:58
  • 2
    @ssc-hrep3 define `document`; everything thatis handled within the browser is handled the same. That is what I am (trying to) explain to you -- it is a human precondition to make a distinction between a PDF and an HTML; but as long as the *files* are loaded only within the browser then all files are handled within the same "safety box". i.e -- **they use CSP**. – Martin Jan 19 '19 at 11:43
  • 1
    Please review the wording of the link from MDN, in my answer : The wording clearly states **scripts** and **browser** and that's it. Any script, in any context - be it Javascript, some JPEG EXIF data, some PDF meta data, is all handled the same way. – Martin Jan 19 '19 at 11:45
  • @Martin I don't see an MDN link in your answer – Stephen R May 30 '19 at 18:52
  • @Martin -- your recent edit really guts your answer. This version was a much better response than what you have now: https://stackoverflow.com/revisions/54204073/5 – Stephen R May 30 '19 at 19:31
  • @StephenR I have re-incorporated my more verbose earlier answers. – Martin Feb 26 '20 at 15:20
  • @Martin Please have a look at the section "[Policy Applicability](https://www.w3.org/TR/CSP2/#which-policy-applies)" of the W3 specification which states that there is a concept of an execution context. This is what I meant with "document". – ssc-hrep3 Sep 14 '20 at 17:58
0

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).

benvc
  • 14,448
  • 4
  • 33
  • 54
0

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

IvanM
  • 2,913
  • 2
  • 30
  • 30