Should Content-Security-Policy header be applied to all resources? - content-security-policy

Is it necessary to apply the Content-Security-Policy Header to all resources on your domain (images/CSS/JavaScript) or just web pages?
For example, I noticed that https://content-security-policy.com/images/csp-book-cover-sm.png has a CSP header.

It is only necessary to apply it to web pages that are rendered in a browser, as CSP controls the allowed sources for content, framing etc of such pages. Typically you will only need to set it on non-redirect responses with content type as "text/html". As CSP can be set in a meta tag, another way to look at it is that it only makes sense on responses that could include a meta tag.
As it is often simpler or only possible to just add a response header to all responses, CSPs are often applied to all content types and codes even though they are not strictly needed. Additionally it is recommended to add a CSP with a strict frame-ancestors to REST APIs to prevent drag-and-drop style clickjacking attacks, see https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html#security-headers.

Related

What is the current protection on an iframe site?

In different site I see different data about what mechanism protects against inserting an iframe.
Tell me, is it possible that these are different levels of protection or are some of these outdated mechanisms?
Same-origin policy prohibits opening an iframe of another domain
At the same time, there is a Content-Security-Policy with the frame-ancestors directive
And there is also X-Frame-Options: DENY
No, the Same-Origin Policy, by itself, doesn't prevent you from framing a document from another origin.
X-Frame-Options and CSP's frame-ancestors directive overlap as defences against cross-origin framing. Only the former is supported in old browsers, though. However, the latter is much more flexible. Also, in case both are present in a response, frame-ancestors takes precedence over X-Frame-Options in supporting browsers.
Finally, don't forget that you can sandbox an iframe in order to further isolate the framing document from the framed document.

Where to specify the Content Security Policy (CSP): on a backend or on a frontend?

As far as I understand, there are two ways to specify the Content Security Policy:
On a server side via headers:
res.setHeader("content security-policy", "default-src: 'none';")
In an HTML-page via meta-tag:
<meta content = "default-src 'none';" http-equiv = "Content-Security-Policy" />
My questions:
What is the difference between these two techniques?
Is it enough to use just one of them?
Which one should I use? Backend, frontend, or both?
P.S. Thanks to How does Content Security Policy (CSP) work?, I know what is the CSP and how does it work. What I want to know, however, is where exactly it is better to set the CSP.
Delivering CSP via HTTP header is a preferred way.
Meta tag has the same functionality but for technical reasons it does not support some directives: frame-ancestors, report-uri, report-to and sandbox. Also the Content-Security-Policy-Report-Only is not supported in meta tag.
In SPA (Single Page Application), a meta tag is traditionally used for CSP delivery, because a lot of hostings do now allow to manage of HTTP header.
When SSR (Server Side Rendering), an HTTP header is used more often.
You can use any technically convenient CSP delivery method (keeping in mind the limitations of the meta tag), but do not use both at the same time. Both policies will be executed one after the other, so in case of differences, a stricter one will apply actually.
Note that:
CSP meta tag should be placed in <head>, otherwise it will not work.
Changing the meta tag by javascript will result in both the old and the new policies being in effect.
in cases of CSP for non-HTML files, the meta tag can not be used technically

When should I use HTTP header "X-Content-Type-Options: nosniff"

I've been running some penetration tests using OWASP ZAP and it raises the following alert for all requests: X-Content-Type-Options Header Missing.
I understand the header, and why it is recommended. It is explained very well in this StackOverflow question.
However, I have found various references that indicate that it is only used for .js and .css files, and that it might actually be a bad thing to set the header for other MIME types:
Note: nosniff only applies to "script" and "style" types. Also applying nosniff to images turned out to be incompatible with existing web sites. [1]
Firefox ran into problems supporting nosniff for images (Chrome doesn't support it there). [2]
Note: Modern browsers only respect the header for scripts and stylesheets and sending the header for other resources (such as images) when they are served with the wrong media type may create problems in older browsers. [3]
The above references (and others) indicate that it is bad to simply set this header for all responses, but despite following any relevant-looking links and searching on Google, I couldn't find any reason behind this argument.
What are the risks/problems associated with setting X-Content-Type-Options: nosniff and why should it be avoided for MIME types other than text/css and text/javascript?
Or, if there are no risks/problems, why are Mozilla (and others) suggesting that there are?
The answer by Sean Thorburn was very helpful and pointed me to some good material, which is why I awarded the bounty. However, I have now done some more digging and I think I have the answer I need, which turns out to be the opposite of the answer given by Sean.
I will therefore answer my own questions:
The above references (and others) indicate that it is bad to simply set this header for all responses, but despite following any relevant-looking links and searching on Google, I couldn't find any reason behind this argument.
There is a misinterpretation here - this is not what they are indicating.
The resources I found during my research referred to the header only being respected for "script and style types", which I interpreted this to mean files that were served as text/javascript or text/css.
However, what they actually referring to was the context in which the file is loaded, not the MIME type it is being served as. For example, <script> or <link rel="stylesheet"> tags.
Given this interpretation, everything make a lot more sense and the answer becomes clear:
You need to serve all files with a nosniff header to reduce the risk of injection attacks from user content.
Serving up only CSS/JS files with this header is pointless, as these types of file would be acceptable in this context and don't need any additional sniffing.
However, for other types of file, by disallowing sniffing we ensure that only files whose MIME type matches the expected type are allowed in each context. This mitigates the risk of a malicious script being hidden in an image file (for example) in a way that would bypass upload checks and allow third-party scripts to be hosted from your domain and embedded into your site.
What are the risks/problems associated with setting X-Content-Type-Options: nosniff and why should it be avoided for MIME types other than text/css and text/javascript?
Or, if there are no risks/problems, why are Mozilla (and others) suggesting that there are?
There are no problems.
The problems being described are issues regarding the risk of the web browser breaking compatibility with existing sites if they apply nosniff rules when accessing content. Mozilla's research indicated that enforcing a nosniff option on <img> tags would break a lot of sites due to server misconfigurations and therefore the header is ignored in image contexts.
Other contexts (e.g. HTML pages, downloads, fonts, etc.) either don't employ sniffing, don't have an associated risk or have compatibility concerns that prevent sniffing being disabled.
Therefore they are not suggesting that you should avoid the use of this header, at all.
However, the issues that they talk about do result in an important footnote to this discussion:
If you are using a nosniff header, make sure you are also serving the correct Content-Type header!
Some references, that helped me to understand this a bit more fully:
The WhatWG Fetch standard that defines this header.
A discussion and code commit relating to this header for the webhint.io site checking tool.
I'm a bit late to the party, but here's my 2c.
This header makes a lot of sense when serving User Generated Content. So people don't upload a .png file that actually has some JS code in it, and then use that .png in a <script> tag.
You don't necessarily have to set it for the static files that you have 100% control of.
I would stick to js, css, text/html, json and xml.
Google recommend using unguessable CSRF tokens provided by the protected resources for other content types. i.e generate the token using a js resource protected by the nosniff header.
You could add it to everything, but that would just be tedious and as you mentioned above - you may run into compatibility and user issues.
https://www.chromium.org/Home/chromium-security/corb-for-developers

Can Content-Security-Policy and Content-Security-Policy-Report-Only headers coexist without interfering with each other

I am working on addition of Content-Security-Policy-Report-Only header to my company's website. While I was researching on it, I found that a few of the pages already have Content-Security-Policy header set.
I investigated further and found that the directives are not required. Also, default directive used for those pages is 'self' whereas what I am planning to set for report-only is 'https:'
I am not an expert in this area and want to make sure that both header values don't interfere. Hence looking for guidance
If I set report-only for the pages that already has CSP header, is it going to interfere with existing headers? Is the behavior browser dependent?
Any help/pointers will be helpful in deciding.
Thanks!
Content-Security-Policy and Content-Security-Policy-Report-Only have no effect on each other and are entirely independent. Setting both is a common practice when tightening policies. I wouldn't doubt that there has been a bug around this behavior at some point, but the spec is clear.
From Section 5 of the CSP2 Spec
A server MAY cause user agents to monitor one policy while enforcing another policy by returning both Content-Security-Policy and Content-Security-Policy-Report-Only header fields. For example, if a server operator may wish to enforce one policy but experiment with a stricter policy, she can monitor the stricter policy while enforcing the original policy. Once the server operator is satisfied that the stricter policy does not break the web application, the server operator can start enforcing the stricter policy.
Based on the link here, server must not send both headers in the same request.
Here is the original text: A server MUST NOT provide Content-Security-Policy header field(s) and Content-Security-Policy-Report-Only header field(s) in the same HTTP response. If a client received both header fields in a response, it MUST discard all Content-Security-Policy-Report-Only header fields and MUST enforce the Content-Security-Policy header field.

Content-Security-Policy (CSP) for every page?

I understand the benefits of using CSP, but is it a waste to send those headers for anything other than HTML files? Do I need to send CSP headers on an image, for example? For a .js file?
The Content-Security-Policy header only makes sense on HTML pages.
A security header that would make sense for a image or other resource would be Access-Control-Allow-Origin. But that is restrictive by default, so you don't need to do anything with that.

Resources