0

The W3C spec for Content-Security-Policy or Mozilla CSP docs would be the definitive source for this answer, but it does not seem covered, so I'm asking here for answers based on people's experience. If my understanding is correct, then I'll probably contact the W3C spec authors.


My understanding is that browsers have implemented their CSP engines as an extension of the page DOM; ie a CSP is associated with a page, not with a request / response.

Under my understanding, a CSP delivered in the following ways is useful:

  • As an HTTP response header (or <meta> tag) on top-level HTML content.
  • As an HTTP response header (or <meta> tag) on nested / framed content (I assume this would fall under section 3.4: Enforcing multiple policies, and would further restrict the first CSP)
  • As a <meta> tag in addition to an HTTP response header in either of the above (I assume this would fall under section 3.4: Enforcing multiple policies, and would further restrict the first CSP).

Under my understanding, a CSP delivered in the following ways is useless; ie completely ignored by the browser and a waste of bandwidth:

  • As an HTTP response header on content that is not HTML (ie on a response that is Content-Type: text/javascript, application/json, text/css, text/plain, application/gzip, image/jpeg, etc).

So I guess I have two questions here:

  1. Does it do anything to put a CSP header responses that are not web pages (ie on REST APIs, files, javascript, etc)?
  2. Is this mentioned anywhere in the W3C spec (and I can't read), or would it be worth asking the authors to add a section "3.x: Applicable content types") ?
2
  • 2
    "Is this mentioned anywhere in the W3C spec" - I think it is explained in 3.5. Policy applicability. "Does it do anything to put a CSP header responses that are not web pages" - yes, with SVG, which is the other thing which can embed content by its own. Commented May 31, 2021 at 17:22
  • 1
    @SteffenUllrich WOW! Yup, I am blind. That's exactly the section I was looking for; it's even formatted as a table and everything! Commented May 31, 2021 at 18:18

3 Answers 3

2

Self-answer: turns out I can't read. Thanks to @SteffenUllrich in comments.

Section 3.5. Policy applicability is exactly what I was looking for.

Summary so this is not a link-only answer (from the CSP Level 2 December 2016 version):

  • Top-level Contexts: ex.: HTML, SVG are mentioned explicitly. Use the policy delivered with the resource.
  • Embedded Contexts: ex.: iframe, object, embed, embedded SVGs, javascript workers that are independent from the page. Use the policy delivered with the resource, fall back to the policy of the creating context if the resource was delivered via a data: blob or something other mechanism that does not give the opportunity to provide a CSP.
  • Subresources: ex.: everything else. Policy of the including context.
1

CSP headers generally apply to things that are Documents; that is, things with a DOM. Usually, that covers HTML and XHTML, but it can also cover SVG and generic XML (if the browser supports XSLT). Since SVG supports JavaScript, it can be very useful to use a CSP header there, for example. Outside of Documents, global objects, such as a web worker or worklet, can also have CSP policies applied. Other items, such as individual assets, aren't affected.

However, because many user-agents allow visiting a URL for an asset directly (e.g., an image or a PDF) and then consider that to be a Document, combined with the fact that some browsers perform Content-Type sniffing, which can do things like guessing that JSON with embedded HTML is HTML, it's generally a prudent to add a CSP header to all HTTP endpoints. Usually a simple default-src 'none' is sufficient, and HTTP/2 header compression is very effective on requests after the first.

You can see this GitHub issue for more details.

1
  • This does not exactly answer the question I asked (I self-answered below); but I like the suggestion that sticking default-src 'none' is fairly low bandwidth and then you just don't have to worry about it, so +1. Commented May 31, 2021 at 18:27
1

My understanding is that browsers have implemented their CSP engines as an extension of the page DOM; ie a CSP is associated with a page, not with a request / response.

The term "page" is too vague, I would formulate it in slightly different:
CSP operates based on origins and browsing contexts.

Under my understanding, a CSP delivered in the following ways is useful:

There are more options: a few meta tags (including ones dynamically created by JavaScript), a few HTTP headers and any of their combinations. Open link https://contacts.google.com/ (you should be logged in) and checks Network tab in the Dev Tool - you'll see that Google uses 2 CSP HTTP headers: enter image description here

• As an HTTP response header (or tag) on nested / framed content (I assume this would fall under section 3.4: Enforcing multiple policies, and would further restrict the first CSP)

In case of framed content is loaded using network schemes (http: / https), it will be created an isolated browsing context - parent context CSP will not acts inside.
In case iframe with data:-Url or blob:-Url - browsing context will not be isolated from point of view CSP. The same is for <iframe srcdoc=>.

Under my understanding, a CSP delivered in the following ways is useless; ie completely ignored by the browser and a waste of bandwidth:
• As an HTTP response header on content that is not HTML (ie on a response that is Content-Type: text/javascript, application/json, text/css, text/plain, application/gzip, image/jpeg, etc).

In a separate browsing context CSP is not ignored. Open in Chrome this robots.txt having text/plain MIME and check browser console - you'll see that CSP blocks inline styles. Yes, inline styles in robots.txt file, because all you mentioned above MIME types are rendered as HTML in a separate browsing context.

  1. Is this mentioned anywhere in the W3C spec (and I can't read), or would it be worth asking the authors to add a section "3.x: Applicable content types") ?

Please note that section you refer to is not normative and belongs to an obsolete CSP2 spec. Firefox has been unable to implement normative CSP sections for years.
In addition, the points of view of browser vendors differ on some issues, for example, CSP for workers.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .