Closed Bug 1447631 Opened 6 years ago Closed 6 years ago

Several CORS security issues in browsers and specs, asking for comments

Categories

(Core :: DOM: Core & HTML, defect, P3)

defect

Tracking

()

RESOLVED FIXED

People

(Reporter: whucjj, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: sec-vector, Whiteboard: paper presented Aug 2018)

Attachments

(1 file)

Attached file CORS-paper.pdf
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36
Firefox for Android

Steps to reproduce:

Hello,

I'm Jianjun Chen from Tsinghua University. Recently we conducted a security analysis on CORS(Cross Origin Resource Sharing) protocol and discovered a number of new CORS-related security issues. We tested mainstream browsers and found Firefox browser is affected.(See details in the attached paper)

The issues can be classified into three categories: 1) CORS relaxes the cross-origin “write” privilege in a number of subtle ways that are problematic in practice; 2) CORS brings new forms of risky trust dependencies into web interactions; 3) CORS is generally not well understood by developers, possibly due to its inexpressive policy and its complex and subtle interactions with other web mechanisms, leading to various misconfigurations.

Here are two demo videos of CORS-related attacks in Google drive:

[1] https://drive.google.com/open?id=11f010CZLojF2d_3Sa--QYs0vzY3bdVJA
[2] https://drive.google.com/open?id=0ByM36MBckzBaUmtnVmlfdXNlcHc

The first video demonstrated that malicious websites can launch RCE attacks on victim's internal server by crafting a malicious Content-Type header through CORS interfaces and exploiting Apache struts s2-045 vulnerability(CVE-2017-5638). 

The second video demonstrated that malicious websites can create a new file in victim's local file system, by exploiting Mac's built-in Apple file server. 

For more technical details and other cases, please refer to the attached paper.

Note that those cases in the paper are some examples,  we believe there are many other similar CORS exploits in the real world.

As many of those problems are not just implementation flaws, but fundamental issues in CORS protocol, we would like to hear your thoughts or comments, especially how to mitigate those attacks.

Thanks very much~

Jianjun Chen
Dan, who's an appropriate person to look into this (ie who knows our CORS implementation and/or has participated in some of the spec design / work)?
Flags: needinfo?(dveditz)
Boris, do you know who might be able to look at this paper?
Flags: needinfo?(bzbarsky)
Anne seems like an obvious choice.
Flags: needinfo?(bzbarsky) → needinfo?(annevk)
So from a brief skim, the paper has at least these bits:

1) The definition of "CORS-safelisted request header" for Content-Type as doing the check after extraction (in the <https://fetch.spec.whatwg.org/#extract-header-values> sense) and after dropping MIME parameters.  This means that CORS can send preflight-less requests with arbitrary junk embedded after ';' or ',' in the Content-Type header, and that allows attacks targeting servers suffering from http://cve.circl.lu/cve/CVE-2017-5638 for example.  Importantly, this allows crafting requests that are not possible with HTML <form>. 

2) There is generally no requirement that the safelisted header values comply with the spec for those headers.  That means you can try to put attacks in there.

3) Allowing general cross-site requests with cookies and settable headers allows a site to measure the size of the cookie header being sent (because servers have hardcoded size caps on headers).

4) CORS allows easily sending arbitrary bodies as POST with the three whitelisted request Content-Type values ("text/plain", "application/x-www-form-urlencoded", and "multipart/form-data").  HTML <form> cannot do that (though the actual constraints on it are pretty subtle and mostly have to do with whether you end up having byte sequences that look like unpaired \r or unpaired surrogates).

5) People often set ridiculous Access-Control-Allow-Origin headers.  The thing that jumped out at me is that of sites the authors examined that are loaded over https:// and include CORS headers 12.7% allow http://my-domain-name.  That, of course, means that any MITM attacker can read stuff from those sites.  This seems like something we should treat akin to mixed-content blocking and just disallow...

6) Any time you put a site in your Access-Control-Allow-Origin, an XSS on that site becomes a data read on that site.  This is something CORS users may not sufficiently understand.  It's not clear to me that there's much that can be done here; the whole premise is that you trust the other person to read you, and if they're not trustworthy enough you should not trust them.

7) Sending correct CORS headers is hard (e.g. you have to dynamically generate them if you want to allow access from two or more origins, instead of just declaratively listing those two origins).  This part was certainly discussed during development of the spec; I assume Anne knows the tradeoffs involved better than anyone.

8) Caches and servers can interact in bad ways when the server does not set "Vary: Origin".  Maybe we can impute that on the browser side....
Jianjun, there's a typo in section 6.1 item (2) sub-item (iii) (not escaping '.').  It has "wwwaexmaple.com" where it means "wwwaexample.com".

In general, I really like this work; having empirical data like this about how things break down in practice is wonderful!
Flags: needinfo?(whucjj)
Group: firefox-core-security → core-security
Status: UNCONFIRMED → NEW
Component: Untriaged → DOM
Ever confirmed: true
Product: Firefox → Core
Also, Jianjun, I assume you're reaching out to Chrome as well, so if we need to cc some of their security folks on this report that won't be a problem, right?
Thanks very much for your reply. And also thanks for pointing out the typo, I will revise it in the paper.

No problem, I have reported it to Chrome team on bugs.chromium.org. Thanks~
Flags: needinfo?(whucjj)
Most of what's listed in comment 4 is known and accepted/enshrined as same-origin policy extensions (much like <form> is an enshrined extension). 

With regards to 1, https://github.com/whatwg/mimesniff/issues/30 has some information on defining parsing of Content-Type better. I think we already made fixes here for CORS in the past and therefore the request and response parser are different. (The other question I have here is will any research get implemented. I still haven't seen much movement on improved MIME type parsing interoperability, which is a subset of the problem here.)

As for 5, if we forbid HTTP to fetch HTTPS resources we make HTTPS migration much more difficult. I guess we could put telemetry in place to see how often it happens (ideally partitioned by credentials mode so we could consider to continue allowing non-credentialed fetches).
Flags: needinfo?(annevk)
> Most of what's listed in comment 4 is known and accepted/enshrined as same-origin policy extensions

While true, the question is whether this was a mistake, given that it's opening up real-life, not just theoretical, security holes...
I forgot to mention that 2 is being tracked by https://github.com/whatwg/fetch/issues/313 and https://github.com/whatwg/fetch/issues/382. Contrary to what the paper suggests what browsers are doing now isn't considered a contradiction of HTTP. We don't expect browsers to validate HTTP fields they know about it, unless that's explicitly called out. If they did that would kinda defeat the purpose of a generic HTTP API, but for these cross-origin scenarios it certainly makes sense to impose more restrictions.

3 we could also tackle by requiring safelisted headers to not have values that exceed 128 bytes or some such and dropping the entire header on the floor otherwise.
Group: core-security → dom-core-security
Hi, 

Thanks very much for all your valuable comments, making the world a safer place.

Our paper has been accepted by USENIX security 2018, so we need to present this work in August at the conference. We would appreciate it if you could fix these issues before that time. Please let us know if you need more time to solve them.

Thanks again for your efforts. If you need any help(eg. testing experiments), please let us know. We are very glad to assist you in solving these issues.

Thanks,
Jianjun Chen
Anne, who can speak to implementing fixes per comment #11?
Flags: needinfo?(annevk)
Christoph will look into ownership of CORS and get back to us mid next week.

Jianjun, I think the main problem here will be identifying what to change, how to change it, and whether such changes will break sites. If you see ways you can assist with that it'd be much appreciated.

Limiting the amount of bytes you can set in a request header value is probably the most straightforward and solves 3. Whether that breaks anything we could test in Firefox Nightly and Beta. Validating header values would be much more involved unfortunately, as header value parsing is generally poorly standardized (so we'd have to do that and figure out all the quirks).
Flags: needinfo?(annevk) → needinfo?(ckerschb)
Flags: needinfo?(dveditz)
Whiteboard: paper presented Aug 2018
Hi Anne, 

Thanks very much for your reply.

As far as I can see, there might be two ways to mitigate the cross origin sending attacks:

1. More restrictive sending permissions
a) Regarding malicious header attacks(issue 1, 2), I agree with you. Grammar checks on header values may be difficult. Maybe simply disallowing `(`, `{` and other unsafe characters (as Safari’s doing) is a first approximation.
  
b) I agree with you on limiting header length to solve issue 3.

c) File upload CSRF attack might be difficult to be addressed by this approach, because parsing request bodies in hope of preventing mismatches between the content type declared and the content delivered is not easy. The second approach below might be able to solve it.

d) To address attacks on AFP server(issue 4), limiting access to the AFP port is a straightforward option, but I’m a bit worried that there may be many other similar service exposed. Maybe disallowing(or triggering preflight for) some characters(eg. \x00) is worth a try.

This approach can solve most of these issues without requiring application changes, but it also has a drawback. It increases the complexity of CORS,  which may make developers confused and bring unexpected security troubles, as Jonas said earlier(https://github.com/whatwg/fetch/issues/313).

2. Always preflight
Another more fundamental approach is always preflight. The root cause of these problems is that browsers allow malicious sites to send attacker-crafted data directly, without asking the server whether is willing to be involved into the communication.  Thus, browsers can send a preflight request for cross origin requests that allow users to customize headers and body, to get sending permission from servers.   It’s also an intuitive idea from access control perspective, all the network access(including sending requests and reading responses) are authorized by server-side.  

This approach may break some websites and requires further testing experiments, but it provides an unified way to solve these problems fundamentally.

Additionally, to address attacks against intranet services, Chrome is considering preventing access to localhost/RFC1918 addresses from public websites. (https://bugs.chromium.org/p/chromium/issues/detail?id=378566). 

Thanks
Jianjun
Jianjun, thanks for sharing your thoughts. For 1a and 1b I created https://github.com/whatwg/fetch/pull/736. I'd like to acknowledge you, but since this is a confidential bug I haven't mentioned you directly. Would you be okay with being listed in the acknowledgments of Fetch as "Jianjun Chen" (alternative is okay as well, see https://fetch.spec.whatwg.org/#acknowledgments for what is there today)?

For 1d we have https://github.com/whatwg/fetch/issues/694 on record. I don't know if Chrome has blocked it already, or whether the additional port I found should be blocked, but I agree that's something we should investigate.

That leaves 1c and 2, neither of which seem very doable.
Anne, thank you very much for the acknowledgment.  No problem, it’s my honor to be listed in the acknowledgments of Fetch. 

FYI,  here are two other suggestions which might be helpful to reduce CORS misconfiguration problems.

1.  Recently we are reporting CORS misconfiguration vulnerabilities to websites, we have found that many developers seem unaware of many CORS misconfiguration security risks. Thus, I wonder if Fetch standard can add a security consideration section(like IETF’s HTTP standard, https://tools.ietf.org/html/rfc7230#section-9.1), to inform web developers of known CORS security risks. It could be helpful for web developers to understand and use CORS correctly. We can help write a draft if needed.

2. Regarding some insecure CORS configurations(like HTTPS websites trust HTTP domain and websites trust null ), I agree with you.  Prohibiting such configurations in browsers may break some websites. I wonder if browsers could show some warning messages for them,  to inform web developers that these configurations are insecure. Because it seems to us that many developers are not aware of their security implications. 

Thanks,
Jianjun
(In reply to Anne (:annevk) from comment #13)
> Christoph will look into ownership of CORS and get back to us mid next week.

Historically CORS used to live in Necko; after the introduction of dom:security the new module seemed like a better fit. With the introduction of fetch, it feels to me that CORS belongs into fetch. Anyway, I discussed things with a few people and we all agree that we would implement required/proposed changes if they make into the spec. Folks who can implemented would be me and baku and then obviously we have Dan and Bkelly who could help with sanity checks on our side. I hope that answers your question.
Flags: needinfo?(ckerschb)
Jianjun, I've updated the PR to acknowledge you. As for the suggestions: 1) seems very reasonable, especially if you help out. Fetch does already contain a bunch of advice so we might want to provide some pointers to that as to not have too much duplication. 2) I'm a little worried about false-positives here. There's also a push for HTTPS already that should help.
Blocks: fetch
Depends on: 1465465
Hi, Anne, thanks a lot for the acknowledgment. OKay, we'll write a draft about the security consideration section, and then ask you to revise it.
Christoph, is there more work to be done (other than bug 1465465)?
Flags: needinfo?(ckerschb)
Priority: -- → P3
All the relevant topics seem to be captured in fetch issues. As those are resolved in the spec we'll need to generate bugs to implement the changes, but doing it all in this bug would be a big mess.
Status: NEW → RESOLVED
Closed: 6 years ago
Flags: needinfo?(ckerschb)
Keywords: sec-vector
Resolution: --- → FIXED
Group: dom-core-security → core-security-release
I filed bug 1483815 to implement CORS restrictions as per comment 22.

I also tried to analyze this issue again to make sure there are no oversights. From comment 4:

 1. Still needs to be addressed, filed https://github.com/whatwg/fetch/issues/790.
 2. Fixed in the standard.
 3. Fixed in the standard.
 4. WONTFIX.
 5. See comment 8, I suspect WONTFIX.
 6 & 7. Unfortunate, but not something we can really solve.
 8. I suspect WONTFIX, given unwillingness from other browsers to go the extent we already have here, see https://github.com/whatwg/fetch/issues/307.

From comment 14 (see also comment 15 for rationale):

 1abd: fixed.
 1c & 2: WONTFIX.
Depends on: 1483815
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Component: DOM → DOM: Core & HTML
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: