Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New CSP Requirement #1311

Closed
jmanico opened this issue Jul 3, 2022 · 81 comments · Fixed by #2337
Closed

New CSP Requirement #1311

jmanico opened this issue Jul 3, 2022 · 81 comments · Fixed by #2337
Assignees
Labels
1) Discussion ongoing Issue is opened and assigned but no clear proposal yet Community wanted We would like feedback from the community to guide our decision otherwise we will progress V50 Group issues related to Web Frontend _5.0 - prep This needs to be addressed to prepare 5.0

Comments

@jmanico
Copy link
Member

jmanico commented Jul 3, 2022

I suggest we have a CSP requirement that moves folks away from allow-lists to a nonce or hash strict-dynamic policy (CSP3 stuff) which is much easier to deploy and more secure.

@elarlang
Copy link
Collaborator

elarlang commented Jul 3, 2022

Another CSP related discussion: #1297

@tghosth
Copy link
Collaborator

tghosth commented Jul 26, 2022

@jmanico are you able to draft the suggested text?

@Sjord
Copy link
Contributor

Sjord commented Aug 13, 2022

I would also recommend CSP3 with nonces, but I would not require it. For some applications a CSP with allow-lists works fine and provides adequate security. I would not require these applications to move to CSP with nonces.

@tghosth
Copy link
Collaborator

tghosth commented Sep 13, 2022

Seemed to be support for CSP staying as Level 1 in #1297 so I closed that but I think we still need to decide how we want it to read in 5.0. Currently it looks like this:

14.4.3

[MODIFIED] Verify that a Content Security Policy (CSP) response header is in place that helps mitigate impact for XSS attacks like HTML, DOM, CSS, JSON, and JavaScript injection vulnerabilities.

@jmanico or @Sjord could you make any sensible or more prescriptive modifications here?

@elarlang
Copy link
Collaborator

Problem 1: Content-Security-Policy also is defense against ClickJacking or User Interface Redress in general. At the moment it's covered with separate requirement (14.4.7), but hopefully soon we can get rid of X-Frame-Options part as IE is almost not used already.

Problem 2: maybe we should set the focus of the wording from "mitigating XSS" to "loading and communicating only with allow-listed resources". Or we can ask "fetch, document, navigation and reporting directives are all set" / for loading and communicating only allow-listed resources / for mitigating XSS attacks

@tghosth
Copy link
Collaborator

tghosth commented Sep 14, 2022

Ok, to me Content Security policy is a well known enough control that we don't need to see what it protects against but rather be more prescriptive about how it should be considered which is what I am looking for suggestions for :)

We could also split into multiple requirements for L1, L2 and L3

@tw2as
Copy link
Contributor

tw2as commented Oct 20, 2022

I totally agree with @Sjord comment: here.

IMO the end solution should be minimum set of CSP rules that should be applied at each level eg. not allowing script-src=unsafe-inline from L2 etc.

In order not to make it too verbose it can be based on CSP tools (like Google CSP Evaluator or CSP Auditor - Burp Suite Extension) and not allow for High severity finding from L2 and Medium severity finding from L3

@elarlang
Copy link
Collaborator

If we want say in details what CSP should do, we need entire paragraph of requirements for that.

Using nonces are better and more flexible, but at the same time - I would not say we should block using allow-list method, it does not provide less security. Also, the context - from "XSS" perspective, this requirement is a 2nd layer of defense.

What the requirement should say is that the header must be present for every rendered HTTP responses, including error messages from the webserver.

@tghosth
Copy link
Collaborator

tghosth commented Nov 4, 2022

I also agree with @tw2as here and @Sjord here but I also agree that the requirement cannot be too long.

Can someone come up with a proposed wording or split for the levels?

This should be also considered in #1230

@tghosth tghosth added 3) awaiting proposal There is some discussion in issue and reach to some results but it's not concluded with clear propos _5.0 - prep This needs to be addressed to prepare 5.0 Community wanted We would like feedback from the community to guide our decision otherwise we will progress labels Dec 7, 2022
@jmanico
Copy link
Member Author

jmanico commented Jan 2, 2023

I am ok to drop this and not get over CSP perscriptive

@tghosth
Copy link
Collaborator

tghosth commented Jan 3, 2023

to be honest, I would like it to be slightly more prescriptive but I don't want to have to define the text myself :)

@elarlang
Copy link
Collaborator

elarlang commented Jan 3, 2023

Do we talk about new CSP Requirement like the issue title says or we talk about updating current requirement?

With current requirement I would use my previous proposal as input: Or we can ask "fetch, document, navigation and reporting directives are all set" / for loading and communicating only allow-listed resources / for mitigating XSS attacks.

@jmanico
Copy link
Member Author

jmanico commented Jan 3, 2023

allow-lists are not at all recommended for CSP policies. Nonce based policies are way more secure.

https://research.google/pubs/pub45542/
https://www.researchgate.net/publication/313452289_Adopting_Strict_Content_Security_Policy_for_XSS_Protection

@tw2as
Copy link
Contributor

tw2as commented Jan 5, 2023

I would recommend the following:

For the CSP section description:

Any new web project should have a CSP implemented at the beginning of the project and initially be set very strictly. Then during the implementation it might be loosen up depending on the specific needs and accepted risks in the project.

For legacy applications CSP implementation should start with using Content-Security-Policy-Report-Only with report-uri (over https) in order to report CSP violations.

The initial CSP can start with:

default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
form-action 'self';
frame-ancestors 'self';
base-uri 'self';
object-src 'self'; 

Please note:

  • 'unsafe-inline' should be removed if possible
  • any of 'self' should be replaced with 'none' if possible

It's highly recommended to use CSP validator (like csp-evaluator.withgoogle.com) to verify the strength of the CSP rules.

The actual ASVS requirements:

From Level 1: CSP should be implemented without 'unsafe-eval', should be checked with CSP validators and be as strict as possible.

From Level 2: CSP should be implemented without 'unsafe-inline' in script-src

From Level 3: CSP should be checked with CSP validators and have no Red / High severity findings. Every finding should be and addressed and secured in some other way.

@tghosth
Copy link
Collaborator

tghosth commented Jan 5, 2023

I really like this idea @tw2as.

For your L1 control, is "should be checked with CSP validators and be as strict as possible." practical/testable?

@elarlang
Copy link
Collaborator

elarlang commented Jan 5, 2023

For me it's wrong direction. This requirements does not describe any rules other than "it should exist".

What is "valid" validator? What is "as strict as possible"? The requirement does not describe, what must be achieved.

In "initial CSP" - why not object-src with none, base-uri with none etc? My point is, we can not say any starter CSP as every application is different.

Basically we just need to sent the message, at via browser, (in HTML or JavaScript; injection or execution situation - it should not be possible to do any communication for loading resources or send requests which are not valid based on application needs.

@tw2as
Copy link
Contributor

tw2as commented Jan 5, 2023

@elarlang - I get your point that initial CSP wouldn't work for some projects. How about the following CSP section description?

Any new web project should have a CSP implemented at the beginning of the project and initially be set very strictly by disabling every CSP directive by setting it's value to 'none'. Then during the implementation it might be loosen up depending on the specific needs and accepted risks in the project.

For legacy applications CSP implementation should start with using Content-Security-Policy-Report-Only with report-uri (over https) in order to report CSP violations.

It's highly recommended to use CSP validator (like csp-evaluator.withgoogle.com) to verify the strength of the CSP rules.

@tghosth - I get your porint that some of those requirements are not testable. If we can to base the requirements on external CSP validator (which I believe is updated more often then the ASVS itself) then I would base it on https://csp-evaluator.withgoogle.com.

Ideally I would prefer to force no high severity findings from L2 and no medium severity findings from L3 but I guess for some projects (especially legacy) it could be to difficult to achieve therefore I propose the following:

From Level 1: Verify that a Content Security Policy (CSP) response header is in place which helps mitigate impact for XSS attacks like HTML, DOM, JSON, and JavaScript injection vulnerabilities and that it does not have 'unsafe-eval' value.
From Level 2: Verify that a Content Security Policy (CSP) response header does not have 'unsafe-inline' value in 'script-src' directive.
From Level 3: Verify Content Security Policy (CSP) response header value with CSP validator (https://csp-evaluator.withgoogle.com/) to make sure that it does not have any High severity findings.

@jmanico
Copy link
Member Author

jmanico commented Jan 7, 2023 via email

@tghosth tghosth added 1) Discussion ongoing Issue is opened and assigned but no clear proposal yet and removed 3) awaiting proposal There is some discussion in issue and reach to some results but it's not concluded with clear propos labels Jan 8, 2023
@tghosth
Copy link
Collaborator

tghosth commented Jan 8, 2023

@elarlang I think that @tw2as is on the right track as long as the suggestions are testable/verifable.

@tw2as Jim's original request was to focus around a "nonce or hash strict-dynamic" type policy but it looks like that is not specified by your requirements, are you able to clarify that in your suggested text?

@elarlang
Copy link
Collaborator

elarlang commented Jan 8, 2023

From @jmanico

Strongly disagree to suggest whitelist policies like this. Nonce & strict-dynamic policies are much much stronger.

Jim, fight mode on and not reading? :)

Where exactly in my comment (#1311 (comment)) I say anything about whitelist?

Basically we just need to send the message, at via browser, (in HTML or JavaScript; injection or execution situation - it should not be possible to do any communication for loading resources or send requests which are not valid based on application needs.

In fact, I don't. It's achievable using allow-lists, it's achievable using nonces. And like we have discussed here before - nonce and strict-dynamic is not something we can force to be used over allow-list approach. Application is not more vulnerable when it uses allow-listed sources correctly.

With nonces I think you may have problems when you try to cache static content, as nonce itself is not static and cacheable.

I still stand for my previously linked comment and we should not say anything about script-src in CSP, because this is "hidden client-side architecture requirement in CSP"

If we want to force script-src or unsafe-eval or whatever similar to (not) being used, we should declare them as separate requirements and CSP is just "block the functionality if it's not done correctly or an attack (attempt) happened".

From @tw2as

For the CSP section description:

Any new web project should have a CSP implemented at the beginning of the project and initially be set very strictly. Then during the implementation it might be loosen up depending on the specific needs and accepted risks in the project.

For legacy applications CSP implementation should start with using Content-Security-Policy-Report-Only with report-uri (over https) in order to report CSP violations.

I agree with all the content, but I'm not sure, it's a content for the ASVS. Feels more like Cheat Sheet content for me.

From Level 3: Verify Content Security Policy (CSP) response header value with CSP validator (https://csp-evaluator.withgoogle.com/) to make sure that it does not have any High severity findings.

I don't like dependency on external tools, as we don't know what those will do in the future. In a way it's against ASVS versioning - let's say application A was valid against CSP rule on date X, then it was retested again on date Y and it was not valid anymore. In ASVS it could be breaking change. If someone has idea to link requirement text to some tool, then we actually need to point clearly, what we need to achieve (with this tool and without mentioning this tool).

@tw2as
Copy link
Contributor

tw2as commented Jan 9, 2023

@tghosth - it's testable as it requires verification of the CSP response header.
@jmanico - it's a good point to include Nonce although it's important that it's generated every time and it's generated with crypto secure generator.

I understand the point that we don't want to include external tools (I guess it more suitable for Cheat Sheet). I propose the following:

  • From Level 1: Verify that a Content Security Policy (CSP) response header is in place which helps mitigate impact for XSS attacks like HTML, DOM, JSON, and JavaScript injection vulnerabilities and it does not contain 'unsafe-eval' value.
  • From Level 2: Verify that a Content Security Policy (CSP) response header does not contain 'unsafe-inline' value in 'script-src' directive or if it contains 'unsafe-inline' it also must contain a 'nonce' value (which makes 'unsafe-inline' only work with older browsers for compatibility)
  • From Level 2: If Content Security Policy (CSP) response header contains a 'nonce' value, verify that it was generated on every load with a cryptographically secure pseudo-random number generator (CSPRNG).

I am not sure if forcing strict-dynamic over allow-list is nesesery. @jmanico if you think so that it's a case of adding the following:

  • Verify that a Content Security Policy (CSP) response header contains 'strict-dynamic' value if it loads scripts from external domains.

@jmanico
Copy link
Member Author

jmanico commented May 15, 2024 via email

@tghosth
Copy link
Collaborator

tghosth commented May 20, 2024


My thoughts on what has been written:

Instead of saying "Do not use 'unsafe-inline'" we should try to explain the goal of the restriction.

@elarlang I agree that setting out the goal of the requirement is key and ideally focusing the requirement around the goal rather than specific

  • Verify for all pages that a Content Security Policy (CSP) is implemented to ensure the browser only loads/executes explicitly trusted content or content from trusted sources using one or a combination of allow lists, CSP-nonces or CSP-hashes.
  • Verify for all pages that a Content Security Policy (CSP) is implemented to ensure the browser only loads/executes explicitly trusted content using CSP-nonces and/or CSP-hashes.

This definitely seems like the right direction to me @ryarmst @jmanico :)

Slapping a header on an application is easy, but making an existing application work with a strict CSP is hard. (@Sjord)

This is an important point but I also agree with @jmanico that L3 requirements are usually hard and that

I think copy/pasting AI-generated content is not helpful.

@jmanico I think I have to agree with this, the guidance tends to be a little unfocused unfortunately.


My questions

@Sjord @ryarmst @jmanico @elarlang:

  • We have two requirement suggestions above, do we think either of them can be L2?
  • Do we definitely want/need both CSP requirements here?
  • Do we need any other CSP requirements or would these be sufficient together with a reference in the notes to the CSP cheatsheet?

@ryarmst
Copy link
Collaborator

ryarmst commented May 22, 2024

@tghosth on your questions:

  • A full nonce/hash based approach may be too much of a burden for L2, so I would ask: is the effort required to implement an allow-list based approach appropriate for L2 and worth the benefits? Despite the existing evidence of widespread bypasses for this approach in practice, it can be effective depending on the implementation. One of the problems here is how to determine whether an allow-list based approach is sufficiently secure for a given application, but I think this is out of the scope of ASVS requirements. I think perhaps there may even be value in encouraging adoption/implementation, even if the stated requirements are not strict. On that point, perhaps a reasonable requirement for L1 would simply be the implementation of a CSP that defines permitted resources with no specific requirements for how to achieve it. However, as @Sjord noted, implementing any reasonably secure policy may be infeasible for many existing applications and CSP is ultimately a defense in depth mechanism for this use case (restriction of content/resources). I have encountered applications vulnerable to XSS that could not be exploited due to an effective allow-list implementation. I have never encountered an application using unsafe-inline that could not be exploited (if there was a XSS vector).
  • I do not feel strongly either way. They could be combined-as with inline references to L2 vs. L3 requirements, but I think the question of what the core requirements are for each level is best answered by ASVS experts on whether these requirements align in general with L2 and L3 in terms of benefit/effort.
  • I think other CSP use cases are better handled by vector-specific requirements (as noted by @elarlang and as in v4.0.3). I will also comment on update 50.2.1 (v4.0.3-14.4.3) and/or split requirement for content-security-policy #1958

@jmanico
Copy link
Member Author

jmanico commented May 27, 2024

Because Allow-Lists are overall bypassable (93% bypassable) I want to make sure we encourage nonce/hash policies in a very strong way. I vote for L2. Also, CSP policies that try to prevent exfiltration are also weak, and the standard has moved away from trying to plug all the exfiltration vectors. I suggest we focus ASVS CSP requirements on just XSS/content injection defense.

@Sjord
Copy link
Contributor

Sjord commented Jun 4, 2024

I think having a best-effort CSP using allowlists should be L2, and having a watertight CSP using nonces should be L3.

I think script-src 'self' can be part of a watertight CSP. Also, when there is an injection point inside a <script> block, XSS is still possible even with nonces.

and the standard has moved away from trying to plug all the exfiltration vectors

@jmanico This sounds interesting, outside the context of this issue. Do you have additional information on this where I can read more about this?

@jmanico
Copy link
Member Author

jmanico commented Jun 4, 2024

Here is the research on CSP bypasses and similar.

https://speakerdeck.com/lweichselbaum/csp-a-successful-mess-between-hardening-and-mitigation?slide=16
and
https://speakerdeck.com/mikispag/defense-in-depth-techniques-for-modern-web-applications-and-googles-journey-with-csp-michele-spagnuolo-and-lukas-weichselbaum

.. even with a strict allow list, bypasses include:

  1. JSONP endpoints
  2. BASE tag jumping
  3. Object-tag injection
    and more

Screenshot 2024-06-04 at 11 10 12 AM

@Sjord
Copy link
Contributor

Sjord commented Jun 4, 2024

I didn't really ask about CSP bypasses, but about exfiltration vectors. They talk about that in the presentation, but that's only focused on data exfiltration through JavaScript. It still seems valuable to prevent e.g. CSS injection to prevent exfiltrating the CSRF token.

Here's another interesting slide from the same presentation, which could help us determine which CSP directives to require at which levels:

Screenshot 2024-06-04 at 12 04 35

However, I think their level 1 won't allow inline event handlers (i.e. <button onclick="...">, so if an application has that it won't be that easy to deploy.

@jmanico
Copy link
Member Author

jmanico commented Jun 4, 2024

In general, the CSP standard body has stopped trying to prevent data exfiltration with CSP. There are just too many vectors. CSP is really about stopping the initial injection.

@Sjord
Copy link
Contributor

Sjord commented Jun 4, 2024

@jmanico Do you have a source for that? Some publication of the CSP standard body that confirms this?

@jmanico
Copy link
Member Author

jmanico commented Jun 4, 2024

@jmanico Do you have a source for that? Some publication of the CSP standard body that confirms this?

For sure. Let me do a little digging on this and I'll get back to you.

But basically, attackers have developed rather sophisticated techniques that can bypass CSP protections, such as using trusted domains or exploiting browser bugs. CSP is less effective in stopping data exfiltration, especially when attackers use legitimate channels for data transmission.

I'll give you a reference soon.

@jmanico
Copy link
Member Author

jmanico commented Jun 7, 2024

This is from one of the CSP standard body members:

"It's true that CSP isn't suited to prevent data exfil. E.g. it's trivial to use navigation to extract data and there's nothing you can do with CSP to prevent this.

Once the attacker has script execution it's game over. So the primary goal is to prevent that from happening.

I'm not sure if there's an official w3c stance on it, but indirectly this position is confirmed by consensus of deprecating the navigate-to CSP directive.

iirc we also had a slide on this in our 2019 locomocosec talk"

@tghosth
Copy link
Collaborator

tghosth commented Jun 11, 2024

@jmanico, having read back through the comments above and especially @ryarmst's comment I think that it is a little unrealistic for a strict nonce/hash based policy for L2 and an allow list based policy might be more difficult than it is worth.

It makes me thing that the L2 requirement should be non-prescriptive on how it is achieved and the L3 requirement should specify nonce/hash based policy.

For the specific wording, I think it will depend on the discussions in #1958.

@jmanico
Copy link
Member Author

jmanico commented Jun 11, 2024 via email

@elarlang elarlang removed the next meeting Filter for leaders label Aug 15, 2024
@ryarmst
Copy link
Collaborator

ryarmst commented Nov 7, 2024

I have a new set of proposals with a couple options. I removed implementation details while still trying to capture the goal/outcome. If it's not clear enough, implementation specifics can be added. For example, for L3: "This can be accomplished using CSP-nonces and/or CSP-hashes".

Option 1: Single requirement that specifies special L3 requirement.
Option 2: Split reqs into L1/L2 and L3.

All in one:

Verify for all pages that a Content Security Policy (CSP) is implemented to ensure the browser only loads/executes explicitly trusted content or content from trusted sources. For L3 applications, the policy must be strict to prevent the loading or execution of any content or resource that has not been specifically permitted.

L1/L2:

Verify for all pages that a Content Security Policy (CSP) is implemented to ensure the browser only loads/executes explicitly trusted content or content from trusted sources.

L3:

Verify for all pages that a strict Content Security Policy (CSP) is implemented to ensure the browser will not load/execute any content or resource that has not been explicitly permitted.

@jmanico
Copy link
Member Author

jmanico commented Nov 7, 2024

I think we need to add "allow-lists or nonces" to L1/L2 and "nonces" to L3.

cc @elarlang who verbalized he has a different opinion here.

@ryarmst
Copy link
Collaborator

ryarmst commented Nov 7, 2024

Reformulating based on feedback, including:

  • Clarifying the attack to mitigate
  • Specifying the specific CSP mechanisms that are permissible
  • Removing L1 requirement to due coming changes to the levels
  • Distinguishing between the outcome/goal from L2->L3

L2:

Verify that a Content Security Policy (CSP) is implemented for all HTTP responses to ensure the browser only loads/executes explicitly trusted content or content from trusted sources in order to limit JavaScript execution resulting from XSS and related attacks. This can be accomplished using one or a combination of allow-lists, nonces, and hashes.

L3:

Verify that a strict Content Security Policy (CSP) is implemented for all HTTP responses to ensure the browser will not load/execute any content or resource that has not been explicitly permitted in order to prevent any JavaScript execution resulting from XSS and related attacks. The exclusive use of nonces or hashes is required.

@ryarmst
Copy link
Collaborator

ryarmst commented Nov 7, 2024

Reformulating:

  • Single requirement

Verify that every HTTP response contains a Content-Security-Policy response header field which defines all directives required to ensure the browser only loads and executes trusted content or resources in order to limit execution of malicious JavaScript. L3 applications must use a combination of nonces or hashes such as when following "Strict CSP", but L2 applications may use allow-lists if needed.

@tghosth
Copy link
Collaborator

tghosth commented Nov 7, 2024

Looks good to me

@ryarmst
Copy link
Collaborator

ryarmst commented Nov 7, 2024

Awaiting additional feedback. @jmanico @elarlang @cronchie

@ryarmst
Copy link
Collaborator

ryarmst commented Nov 7, 2024

New candidate per @jmanico feedback:

Verify that every HTTP response contains a Content-Security-Policy response header field which defines all directives required to ensure the browser only loads and executes trusted content or resources in order to limit execution of malicious JavaScript. L3 applications must use a combination of nonces or hashes, defining per-response policies with object-src and base-uri both set to 'none'. L2 applications may use allow-lists and a global policy if necessary.

@jmanico
Copy link
Member Author

jmanico commented Nov 7, 2024

Minor wordsmithing:

Verify that every HTTP response includes a Content-Security-Policy (CSP) header field to reducing the risk of malicious JavaScript. For L3, define a per-response policy with nonces or hashes with object-src and base-uri set to 'none'. For L2, allowlists and a global policy may be used.

@elarlang
Copy link
Collaborator

elarlang commented Nov 7, 2024

For L2 application, allowlists and a global policy may be used, for L3 a per-response policy with nonces or hashes with object-src and base-uri set to 'none' must be defined.

@jmanico
Copy link
Member Author

jmanico commented Nov 7, 2024

Taking Elar into consideration.

_Verify that every HTTP response includes a Content-Security-Policy (CSP) header field to reduce the risk of malicious JavaScript. For L2, allowlists and a global policy may be used. For L3, a per-response policy with nonces or hashes, and object-src and base-uri set to 'none,' must be defined. _

@elarlang
Copy link
Collaborator

elarlang commented Nov 7, 2024

mark closes #1311 #1958

jmanico added a commit that referenced this issue Nov 7, 2024
@elarlang elarlang linked a pull request Nov 7, 2024 that will close this issue
elarlang pushed a commit that referenced this issue Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1) Discussion ongoing Issue is opened and assigned but no clear proposal yet Community wanted We would like feedback from the community to guide our decision otherwise we will progress V50 Group issues related to Web Frontend _5.0 - prep This needs to be addressed to prepare 5.0
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants