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

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

Related

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

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.

Is Content Security Policy (CSP) Isolation possible?

Here is the question/problem, I provide a JavaScript from our business domain (e.g. www.mysite.com/js/metrics.js) which is included in over 20 different web apps and include in the head of their documents. It is for analytics tracking. I'm assuming that I need to set a CSP by updating the DOM with a script-src meta tag which only applies to my code and the external JavaScripts it calls (from Akamai CDN assets.adobedtm.com), not the whole web app. Is it possible to do or will my CSP meta tag apply to any external scripts the web app loads and I'd have to know every external JavaScript all the web apps load? Is there any way to achieve this? Any ideas? This is my first time doing CSP so maybe I'm not understanding it correctly... so be gentle!
Thanks!
Yes, your CSP meta tag will apply to any external scripts the web app loads and in common you have to know every external JavaScript all the web apps load.
But if all scripts you load are from assets.adobedtm.com you can just add this source to the script-src directive:
script-src assets.adobedtm.com
and all external scripts from it will be allowed.
Also CSP provides a possibility to do what you want - the 'strict-dinamic' token paired with 'nonce-value' or 'hash-value'. But Safari still does not implemented this (it support by Chrome, Edge and Firefox). If you have CSP with 'nonce-value' like:
script-src 'nonce-SomeSecureValue' 'strict-dinamic';
than:
<script src='https://domain/script.js' nonce='SomeSecureValue'>
will be allowed to load and any its child scripts it inserts will be allowed too.
In case CSP with 'hash-value':
script-src 'sha256-HashOfScriptAllowed' 'sha256-HashOfScript2Allowed' 'strict-dinamic';
than:
<script src='https://domain/script.js' integrity='sha256-HashOfScriptAllowed'>
will be allowed to load and any its child scripts it inserts will be allowed too. But Firefox has a bug and does support 'hash-value' for inline scripts only, not for external.
Alternatively you can use inline <script nonce='SomeSecureValue'> dynamically create script tags and load external scripts</script> and allow it via nonce or hash. All its child scripts will be allowed.
The Safari's 'strict-dynamic' bug can be bypassed using Google's strict CSP.

What is happening when I have two CSP (Content Security Policies) policies - header & meta?

Question is regarding having CSP served twice:
What's the behavior if there is one policy served through the Content-Security-Policy HTTP response header and also another policy specified with the <meta /> element?
Will those two be merged somehow? Or else which one has priority? (I cannot find clear info on this in the spec).
Specific use case might be serving Report-to through the HTTP response header and putting all other restrictions in the <meta /> element — because some of those are generated by webpack - and if I shouldn't be worried about <meta /> shallowed by the HTTP response-header policy.
If you have CSP directives specified both in a Content-Security-Policy HTTP header and in a meta element, the browser uses the most-restrictive CSP directives, wherever specified.
See the details on multiple polices at https://w3c.github.io/webappsec-csp/#multiple-policies and details on using the meta element at https://w3c.github.io/webappsec-csp/#meta-element:
A policy specified via a meta element will be enforced along
with any other policies active for the protected resource, regardless
of where they’re specified. The general impact of enforcing multiple
policies is described in §8.1 The effect of multiple policies.
8.1. The effect of multiple policies
The impact is that adding additional policies to the list of policies
to enforce can only further restrict the capabilities of the protected resource.

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.

Blocking Chrome Extensions from running on my site

As a web developer, is there any way to prevent a user's Chrome extensions from being applied to my site? i.e. a header, meta tag, anything? Additionally, if there is, is there also a way to whitelist particular extensions?
It's not possible. At the web server end, you are only only able to control what the browser will allow you to control. In simple terms, this means you can control the data (HTML, javascript, headers etc) that you send back to it. That's about it.
Can't you create a Content Security Policy (CSP) and block inline javascript and only allow javascript from specific domains? You could even create a CSP in report-only mode and collect violation reports via something like https://report-uri.io/

Resources