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.
Related
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.
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
Should Content-Security-Policy header be in every server response (images, CSS, JS, ...) or only in text/html (.html or HTML output of PHP script)?
Since CSP is a client side protection and only processed by browsers for HTML documents (whether static or dynamically created by PHP or such like) there is no need to have this header on anything but text/html documents.
In fact, as CSP policies can be quite large, there is bandwidth savings to be had by only serving it in HTML document responses.
The one exception at present to this is web workers. However if you are not using them then you can ignore them for now.
Note the current CSP draft spec says in the goals section that CSP is used to give control over:
The resources which can be requested (and subsequently embedded or
executed) on behalf of a specific Document or Worker
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.
for my web application, I'm configuring a set of OWASP security headers, like X-Frame-Options or X-Content-Type-Options. Now I'm wondering whether I should send all those headers for every request, or if I should use them only for specific requests, e.g., use the "full" bunch of security headers for get, post, delete, put, and send only CORS headers for preflight requests.
There is no harm in outputting the full security headers for each content type you serve (e.g. text/html, application/java) and for each request method (GET, PUT, etc).
However the ones that would be applicable for different requests and responses are discussed below.
Regarding returned content types:
X-Content-Type-Options especially needs to be on all content types, as otherwise types such as application/java could be interpreted differently by Internet Explorer with its content-sniffing.
X-Frame-Options for all content types to stop them being framed, although this does not prevent them being loaded by other means (e.g. <img> tag).
X-XSS-Protection added to HTML content types only should be enough.
Content-Security-Policy for HTML content types only should be enough.
Regarding HTTP methods (GET, POST, PUT etc):
Strict-Transport-Security is better if it is output on every request as it will renew the sliding expiration and it will also set the HSTS policy whichever way the resource was first requested.
Public Key Pinning Extension for HTTP for every request, in much the same way as the Strict-Transport-Security header in that once it has been output, the policy will be set. As this is the sooner the better, if the site does this for all requests there is more chance of it being set earlier.