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

having a new sub-section for CORS(e.g. V14.6) and add one more item. #876

Closed
jeremychoi opened this issue Dec 7, 2020 · 52 comments
Closed
Assignees
Labels
1) Discussion ongoing Issue is opened and assigned but no clear proposal yet next meeting Filter for leaders V50 Group issues related to Web Frontend _5.0 - prep This needs to be addressed to prepare 5.0

Comments

@jeremychoi
Copy link
Contributor

Currently, CORS is covered by 14.5.3 in V14.5 "Validate HTTP Request Header Requirements" which won't fit well, because " Access-Control-AllowOrigin header" is a response header, although 14.5.3 also have a part related to the Origin header which is a request header.

I'd suggest adding a new subsection such as 14.6 for CORS and let it include the following items:

14.6.1 Verify that the Cross-Origin Resource Sharing (CORS) Access-Control-Allow-Origin header uses a strict allow list of trusted domains and subdomains to match against and does not support the "null" origin.
14.6.2 Verify that the responses do not include any sensitive information, where they should be responded with Access-Control-Allow-Origin: *

If it makes sense, I'll make a PR soon.

@elarlang
Copy link
Collaborator

elarlang commented Dec 7, 2020

Problems with current 14.5.3 I have described in: #686 (but closed it myself back then). It contains two requirements together the way that it's not understandable, what exactly you need to check:

  • validate Origin request header
  • have whitelist for Access-Control-Allow-Origin response header

Proposed 14.6.2 is something what ASVS miss at the moment, but:

  • if to split current 14.5.3 to validate Origin and build correct Access-Control-Allow-Origin - it can be part of the last one
  • it's quite different, do you have Access-Control-Allow-Credentials: true in the same response or not.

Category - do we consider CORS topic as part of Configuration (V14 subcategory) or part of Web Service (V13 subcategory)

@jmanico
Copy link
Member

jmanico commented Dec 7, 2020 via email

@jeremychoi
Copy link
Contributor Author

jeremychoi commented Dec 10, 2020

I agree with splitting the current 14.5.3 into two separate ones.

Re 14.6.2, I should have provided more details.

If Access-Control-Allow-Credentials: true exists in the same response with Access-Control-Allow-Credentials: *, the browsers will just make the request fail (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials). So IMO we just don't need to care about it.

There are situations where a protection is made by IP addresses or firewall rules(e.g. communication allowed in the intranet), rather than by credentials. In this case, whether or not the Access-Control-Allow-Credentials: true header being returned does not matter, because it's not protected by credentials in the first place. Therefore the best is to have the strict white list in the Access-Control-Allow-Origin header but if inevitably the header needs to be set to *, the sensitive information must not be contained.

Re Jim's "1) The origin header fires automatically for both preflight and simple requests; developers do not do this", attackers can host scripts in their host, phish the victim and let the requests send from there. In that case, the Origin header can be manipulated. So we need to validate the Origin request. (I recently added an example to the web security testing guide, OWASP/wstg@d8d10ff#diff-f9e5b91325a1ae6dc54f7b8fa67a5322757bfa19b5bdbfa2e4ebd3fb198e83c6R75)

How about this?

14.6.1 Verify that the Cross-Origin Resource Sharing (CORS) Access-Control-Allow-Origin header uses a strict white list of trusted domains and subdomains. Where Access-Control-Allow-Origin: * needs to be inevitably returned, verify that the responses do not include any sensitive information.
14.6.2 Verify that the Origin request header is validated to meet the CORS policy.

@jeremychoi
Copy link
Contributor Author

Re: "do we consider CORS topic as part of Configuration (V14 subcategory) or part of Web Service (V13 subcategory)", I think V14 would fit better. Technically, it doesn't necessarily have to be a web service to use CORS, although it's very common.

@elarlang
Copy link
Collaborator

elarlang commented Dec 10, 2020

If Access-Control-Allow-Credentials: true exists in the same response with Access-Control-Allow-Credentials: *, the browsers will just make the request fail. So IMO we just don't need to care about it.

You are mixing Access-Control-Allow-Credentials: * and Access-Control-Allow-Origin: * here, but ok, didn't have this in my mind that credentials are not allowed with * Origin.

But what it means in reality then - "do not show sensitive information for not authorized user" (because cookies are not in request). Is there any point to have this requirement, I'm not really sure. Authorization problems are covered with V4 category requirements. Without authorization problems it does not give anything extra.

Maybe I miss same cases. Where it can cause problems? What is your reason or example, where it causes problems?

@jmanico
Copy link
Member

jmanico commented Dec 10, 2020 via email

@jeremychoi
Copy link
Contributor Author

A common example is, an internal web page which is only accessible from a specific IP address range(e.g. access control via VPN), not via cookies or other Auth mechanism. In this case, a sensitive information could be read if Access-Control-Allow-Origin: * is set. 4.1.1 seems to be most related but, it's not clear to me whether or not VPN could be viewed as a trusted service layer (as defined in V1.5 - where the term "trusted service layer" is used in the ASVS, we mean any trusted enforcement point, regardless of location, such as a microservice, serverless API, server-side, a trusted API on a client device that has secure boot, partner or external APIs, and so on). Otherwise, any other item that would cover this case?

Meanwhile, a question we might need to consider first would be whether or not we want to view the wildcard Access-Control-Allow-Origin as dangerous.

If yes, we should have an additional item to clearly mention that the wildcard needs to be avoided like:

Verify that Access-Control-Allow-Origin: * is not used.

If no (I prefer this as IMO it's an overkill to force not to use the wildcard ACAO at all, except null), my initial suggestion would make sense.

I tried summarizing it again. I added now 'as much as possible' to make it a bit much clearer. BTW, I missed the 'null' part in my last comment. 'null' can be used as a value for the ACAO header, but https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin suggests 'null' should not be used). It'd be good to have a separate item for it. Hence, the final version(any suggestion for better wordings is welcome):

14.6.1 Verify that the Cross-Origin Resource Sharing (CORS) Access-Control-Allow-Origin header uses a strict white list of trusted domains and subdomains as much as possible. Where Access-Control-Allow-Origin: * needs to be inevitably used, verify that the responses do not include any sensitive information.
14.6.2 Verify that Access-Control-Allow-Origin: null is not used.
14.6.3 Verify that the Origin request header is validated to meet the CORS policy.

@elarlang
Copy link
Collaborator

elarlang commented Dec 11, 2020

Otherwise, any other item that would cover this case?

Described situation for me is clear problem with missing authentication and authorization controls. Do not use Access-Control-Allow-Origin: * there makes sense but to set this header does not solve original problem - missing authentication and authorization.

At the same time we can not say do not use Access-Control-Allow-Origin: *, because it is required when you want to share font files from your domain for example (for other sites).

14.6.2 Verify that Access-Control-Allow-Origin: null is not used.

If previous requirement says "use strict white list", then what this one gives extra? Instead of "white list" you may want to use "allow-list" nowadays.

Your proposal:

14.6.3 Verify that the Origin request header is validated to meet the CORS policy.

Current V14.5.2

V14.5.2 Verify that the supplied Origin header is not used for authentication or access control decisions, as the Origin header can easily be changed by an attacker.

For discussion - should those be merged to one requirement or there is point to keep them separately?

@jeremychoi
Copy link
Contributor Author

jeremychoi commented Dec 11, 2020 via email

@elarlang
Copy link
Collaborator

I prefer one Access-Control-Allow-Origin which covers:

  • use allow-list
  • do not use null at all
  • do not use * when serving content

If I take most-widespread mistake what I have seen during pen-test cases then in practice this requirement must send clearly message: do not reflect Origin request header value from user back to user as Access-Control-Allow-Origin response header value.

For Origin header

  • one requirement for "validate against allow-list"
  • one requirement "do not use value for authentication decisions"

If to keep them in V14 category, I prefer to not have separate category for CORS, but just finetuned requirements in V14.4 for ACAO and V14.5 for Origin. I think all those categories and subcategories will be reorganized many times before ASVS v4.1 will be released.

@jmanico
Copy link
Member

jmanico commented Dec 11, 2020 via email

@elarlang
Copy link
Collaborator

Point being, CORS is shitty security. I can just use curl to completely circumvent it.

As CORS is meant for browsers, like you already pointed out yourself, for defending end-users against cross-origin attacks, then parallel with curl does not make sense here. It's kind of the same to say, that defense against CSRF is shitty security because you can bypass it with using curl.

@jmanico
Copy link
Member

jmanico commented Dec 11, 2020 via email

@elarlang
Copy link
Collaborator

Yes, if you use tools for what they are not meant for, they don't do the job you expected.

@jmanico
Copy link
Member

jmanico commented Dec 11, 2020 via email

@jmanico
Copy link
Member

jmanico commented Dec 11, 2020 via email

@elarlang
Copy link
Collaborator

I have not used it as replacement, I have said clearly in every comment, that original access control problems stays. I have not said that you can fix access control with setting up CORS. Don't put words to my mouth (comments).

@jmanico
Copy link
Member

jmanico commented Dec 11, 2020 via email

@elarlang
Copy link
Collaborator

elarlang commented Dec 11, 2020

Just for pun - we are always on the same page when we are commenting same issue ;)

If someone is mixing attack vectors / defenses via victim browser and attack vectors / defenses directly to server, I just can not ignore that. That's why this curl comment and I stand for that.

Takeaway for original issue/topic - category will stay V14 ;)

@jmanico
Copy link
Member

jmanico commented Dec 11, 2020 via email

@jeremychoi
Copy link
Contributor Author

Okay. It will stay in V14. How about having the new V14.6 for CORS?

If to keep them in V14 category, I prefer to not have separate category for CORS, but just finetuned requirements in V14.4 for ACAO and V14.5 for Origin. I think all those categories and subcategories will be reorganized many times before ASVS v4.1 will be released.

Elar said above, whereas I suggested having a new one, so the score now is 1 - 1 :) What do you think, Jim?

@ThunderSon
Copy link
Contributor

ThunderSon commented Dec 16, 2020

I suggest v14.6 HTTP Response Headers, or something to the likes of that.
CORS is there to relax SOP in the browser sandbox on server commands. It is not a "security" header, it's a security-relaxation header to be precise. Not part of 14.4.

I am against discussing the Origin header in the request. It's just an anti-pattern when used (oh it's that origin, let's trust it). It's like telling someone not to shoot themselves in the leg. I know some do it. People do a lot of things that will bring shame to everyone ... Haha.

ACAO: * is all good if a server is meant to serve public requests.
Dynamic ACAO is bad when not properly implemented as it will allow the ACAC header to be served with it, unlike the * value.

I don't mind reviewing this once a PR is opened as this follows closely to the WSTG contribution done by @jeremychoi

Edit: After reviewing 14.4, it seems those are all response headers, so that's an alright point. If CORS needs a special section, CSP does too. CSP is a much harder one to tackle to be honest. The points for the CORS headers (since there are many headers) should be part of 14.4

@jmanico
Copy link
Member

jmanico commented Dec 16, 2020 via email

@jeremychoi
Copy link
Contributor Author

Thank you all for the input. I created a PR, trying to reflect your opinions as much as possible.

Please review. Any feedback will be welcome.

@elarlang
Copy link
Collaborator

elarlang commented Dec 17, 2020

V14.4.8 - ACAO

  • "as much as possible" - not necessary
  • Access-Control-Allow-Origin: * - styling/formatting question, so far we don't have "code style" in requirements

V14.5.3 Origin

  • "is completely" - not necessary
  • maybe something like "validated against defined list of allowed domains" (with correct and nice wording)?
  • "when Access-Control-Allow-Origin header is dynamically configured with its value" - is this part necessary? I think we need to validate Origin header anyway, do we reflect it back to ACAO or not. And if we already validate it, then this last part is not needed in requirement text

@jeremychoi
Copy link
Contributor Author

I will remove them that are stated as "not necessary" and use quotes instead of code style.

"when Access-Control-Allow-Origin header is dynamically configured with its value" - is this part necessary? I think we need to validate Origin header anyway, do we reflect it back to ACAO or not. And if we already validate it, then this last part is not needed in requirement text

It makes sense. I wanted to clarify the situation but removing it is fine. Meanwhile, I still think we might need to mention that it's about CORS so that the requirement looks clearer to audience.

So, for V14.5.3, how does this sound: "Verify that the Origin header is validated against the allow-list to meet the Cross-Origin Resource Sharing (CORS) policy"?

@elarlang
Copy link
Collaborator

One more "spice" removal - V14.4.8 from second part "inevitably" is also not necessary. Hopefully that't it from me :)

@jmanico
Copy link
Member

jmanico commented Mar 13, 2021 via email

jmanico added a commit that referenced this issue Mar 13, 2021
update for CORS after discussion on issue #876
@jmanico
Copy link
Member

jmanico commented Mar 13, 2021

Indeed, it's merged and I'm closing this issue.

@jmanico jmanico closed this as completed Mar 13, 2021
@tghosth
Copy link
Collaborator

tghosth commented Dec 15, 2024

Rise!GIF

@tghosth
Copy link
Collaborator

tghosth commented Dec 15, 2024

We currently have the following requirements:

V50.3 Browser Security Mechanism Headers

# Description L1 L2 L3 CWE
50.3.6 [ADDED, SPLIT FROM 14.5.3] Verify that the Cross-Origin Resource Sharing (CORS) Access-Control-Allow-Origin header field is validated against an allowlist of trusted origins. When "Access-Control-Allow-Origin: *" needs to be used, verify that the responses do not include any sensitive information. 183

V50.4 Browser Origin Separation

# Description L1 L2 L3 CWE
50.4.3 [ADDED, SPLIT FROM 14.5.3] Verify that the Origin header field is validated against a defined list of allowed origins to match the desired Cross-Origin Resource Sharing (CORS) policy. 346

My understanding was that the second requirement comes to handle the case where some sort of IP allowlisting is being used to restrict data but the use of * in ACAO header means that any origin can pull that data, except we now seem to cover that requirement in the first requirement.

My proposal would be to delete 50.4.3. I am struggling to see the attack scenario it prevents.

I would maybe also slightly refine 50.3.6:

# Description L1 L2 L3 CWE
50.3.6 [MODIFIED, MOVED FROM 14.5.3] Verify that the Cross-Origin Resource Sharing (CORS) Access-Control-Allow-Origin header field will only contain values from an allowlist of trusted origins. When "Access-Control-Allow-Origin: *" needs to be used, verify that the responses do not include any sensitive information. 183

@tghosth tghosth reopened this Dec 15, 2024
@tghosth tghosth added 1) Discussion ongoing Issue is opened and assigned but no clear proposal yet _5.0 - prep This needs to be addressed to prepare 5.0 V50 Group issues related to Web Frontend labels Dec 15, 2024
@tghosth
Copy link
Collaborator

tghosth commented Dec 15, 2024

FYI @jeremychoi @jmanico @elarlang

@elarlang
Copy link
Collaborator

TLDR: a quite clear "no" from me to this proposal.

50.4.3 is for "accepting the request". Origin is an important requirement for filtering invalid requests made by JavaScript from third-party sites. It is one solution to mitigate CSRF and to do site isolation (#2409). From this requirement perspective, it does not matter, if is there any ACAO in place - it only matters and focuses, on is the source of the request is validated.

50.3.6 is for "do not leak the response". there is a duplicate part with 50.4.3 that only contains values from an allowlist of trusted origins, but this is in the context of sharing the response with 3rd party.

We also need them as separate requirements, as one is a request, another is a response. It is important that those are not mixed.

@tghosth
Copy link
Collaborator

tghosth commented Dec 15, 2024

50.4.3 is for "accepting the request". Origin is an important requirement for filtering invalid requests made by JavaScript from third-party sites. It is one solution to mitigate CSRF and to do site isolation (#2409). From this requirement perspective, it does not matter, if is there any ACAO in place - it only matters and focuses, on is the source of the request is validated.

If we are mitigating CSRF then I think that should go in the relevant location. I don't see any other real reason to do this. I am not sure what the relevant attack is related to site isolation. I don't see why this deserves a separate requirement. I accept that one is request and one is response but I don't see that a request level requirement is relevant or practical here except in the CSRF context

@elarlang
Copy link
Collaborator

If we are mitigating CSRF then I think that should go in the relevant location.

If it is already in the same section as CSRF, what is the more relevant location?

@elarlang elarlang assigned tghosth and unassigned jmanico and jeremychoi Dec 15, 2024
@tghosth
Copy link
Collaborator

tghosth commented Dec 15, 2024

If we are mitigating CSRF then I think that should go in the relevant location.

If it is already in the same section as CSRF, what is the more relevant location?

I mean it should be in the same requirement because it is solving that single problem

@elarlang
Copy link
Collaborator

elarlang commented Dec 15, 2024

Well, here is again terminology madness as Cross-Origin Request Forgery is called Cross-Site Request Forgery (CSRF).

I can see an argument to merge it with the "CSRF" requirement, but I don't like the idea.

I'm leaning more towards idea of bringing 13.2.5 to this section as well, as this, with a combination of validating the Origin header, is the defense to not bypass CORS pre-flight request criteria, and that is... defense against CSRF.. or CORF.

V13.2.5 Verify that REST services explicitly check the incoming Content-Type to be the expected one, such as application/xml or application/json.

I know that you did not like the idea, but the security point for this requirement is CORS-related and it belongs to V50.

@tghosth
Copy link
Collaborator

tghosth commented Dec 16, 2024

I'm leaning more towards idea of bringing 13.2.5 to this section as well, as this, with a combination of validating the Origin header, is the defense to not bypass CORS pre-flight request criteria, and that is... defense against CSRF.. or CORF.

V13.2.5 Verify that REST services explicitly check the incoming Content-Type to be the expected one, such as application/xml or application/json.

I know that you did not like the idea, but the security point for this requirement is CORS-related and it belongs to V50.

I disagree that this is CORS related. As I recall, certain content types will not trigger a pre-flight which will prevent CSRF. Also, its easier to trigger CSRF with formurlencode. Either way, it will still not allow a full CORS style attack because the response will still not be readable.

There are also good reasons to validate content types so as not to allow requests to be processed in an unexpected way which is a wider problem than CORS. As such, I don't believe 13.2.5 is relevant here.

I can see an argument to merge it with the "CSRF" requirement, but I don't like the idea.

Why not, is there any other specific reason to check the origin? (Remember for CORS config, it is not so much the value of the Origin header as it is allowed values for the ACAO response header.)

It don't see any other reason for this requirement.

@elarlang
Copy link
Collaborator

elarlang commented Dec 16, 2024

I disagree that this is CORS related. As I recall, certain content types will not trigger a pre-flight which will prevent CSRF. Also, its easier to trigger CSRF with formurlencode. Either way, it will still not allow a full CORS style attack because the response will still not be readable.

To have things in context - have you ever made one attack with that? Or ever implemented it?

CORS-safelisted request (previously called "simple request") requires the request Content-Type field to be one of those:

text/plain
application/x-www-form-urlencoded
multipart/form-data

As such, I don't believe 13.2.5 is relevant here.

And proves, that 13.2.5 is exactly the requirement you need for that. You can not bypass pre-flight if you require request content-type to be application/json or application/xml.

Also, its easier to trigger CSRF with formurlencode.

Which makes this as nonsense.

@tghosth
Copy link
Collaborator

tghosth commented Dec 16, 2024

To have things in context - have you ever made one attack with that? Or ever implemented it?

Yeah, stuff like this is a real thing
https://www.directdefense.com/csrf-in-the-age-of-json/#h-manipulating-the-content-type

Also, its easier to trigger CSRF with formurlencode.

Which makes this as nonsense.

Sometimes apps will work with json but will also accept formurlencoded so you can craft a CSRF payload which uses formurlencoded and it will succeed.

And proves, that 13.2.5 is exactly the requirement you need for that. You can not bypass pre-flight if you require request content-type to be application/json or application/xml.

and I am saying that this is for reasons other than CORS

@elarlang
Copy link
Collaborator

Sometimes apps will work with json but will also accept formurlencoded so you can craft a CSRF payload which uses formurlencoded and it will succeed.

This this is the problem to fix not to say 13.2.5 is not valid defense against pre-preflight. 13.2.5 is important requirement for CORS, if there is another meaning in another context, I prefer to make a separate requirement for the other context with a clear definition, what other risk it mitigates.

@tghosth
Copy link
Collaborator

tghosth commented Dec 16, 2024

Well I would actually argue that 13.2.5 is defence in depth for CSRF because the correct fix is what is in 50.4.1. It is irrelevant for CORS because again even if you manage to send the request, you cannot read the response.

I would suggest we move the 13.2.5 discussion to #2472 and focus here on the original point about these two requirements.

@tghosth tghosth added the next meeting Filter for leaders label Dec 17, 2024
@jmanico
Copy link
Member

jmanico commented Dec 17, 2024

Brief note for this discussion, a Simple cross-origin javascript based request requires three sets of criteria to avoid pre-flight as @elarlang was elluding to.

The allowed methods are the only "simple" choice:

  • GET
  • HEAD
  • POST

The only headers which are allowed for simple cross-orgin requests:

There are only three values allowed for Content-Type header for simple requests:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Please note that CORS is not security. It's removing the security of SOP. SOP is security that CORS breaks. But also, API endpoints per other requirements require active sessions. As long as your API endpoint is not public and properly requires an active session token and proper access control, then misconfigured CORS rarely leads to a security issue at the API level.

Misconfigured client side CORS based request address can lead to sending sensitive data to the wrong server, but this could be for any form or client request with a mistyped URL, not just CORS.

@tghosth
Copy link
Collaborator

tghosth commented Dec 18, 2024

Discussed with @elarlang. Current proposal is to merge origin validation into CSRF as it more closely relates there.

Opened #2481 to discuss this and will close this issue.

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 next meeting Filter for leaders V50 Group issues related to Web Frontend _5.0 - prep This needs to be addressed to prepare 5.0
Projects
None yet
Development

No branches or pull requests

5 participants