Leveraging XHR and CORS to hijack users' CSRF Token

RESOLVED FIXED

Status

Mozilla Developer Network
Security
RESOLVED FIXED
2 years ago
7 months ago

People

(Reporter: Yassine ABOUKIR, Unassigned)

Tracking

({sec-moderate, wsec-csrf, wsec-disclosure})

unspecified
All
Other
sec-moderate, wsec-csrf, wsec-disclosure
Bug Flags:
sec-bounty +

Details

(Whiteboard: [specification][type:bug])

(Reporter)

Description

2 years ago
What did you do?
================
HTML5 brings us Cross Origin Resource Sharing or CORS which is a mechanism that enables a web browser to perform "cross-domain" requests using the XMLHttpReques.

Every page that is supposed to be accessed by foreign sites, should respond with the ‘Access-Control-Allow-Origin' header in the HTTP Response header and specify a white list of websites that are allowed to access its content. 


What happened?
==============
MDN set the Access-Control-Allow-Origin with the wildcard '*', which means that all websites are allowed to access MDN sensitive pages.

This security vulnerability would allow any attacker to retrieve the content of each page and extract the CSRF authenticity token from the input attribute.

<input type="hidden" name="csrfmiddlewaretoken" value="">

Consequently, the attacker can easily bypass the implemented protection mecanism to easily craft a CSRF attack against MDN connected users.

Proof Of Concept :
------------------
If you are connected to your MDN account and access the following page : http://yassineaboukir.com/mozilla.html
Your CSRF token will be extracted and sent to be stored in : http://yassineaboukir.com/cookielog.txt

What should have happened?
==========================
You should review the domains which are allowed by the CORS policy in relation to any sensitive content within the application, and determine whether it is appropriate for the application to trust both the intentions and security posture of those domains. 

Is there anything else we should know?
======================================
(Reporter)

Updated

2 years ago
Component: General → Security
Flags: sec-bounty?
:ulfr - how viable and risky does this seem?
Flags: needinfo?(jvehent)
(Reporter)

Comment 2

2 years ago
The risky part of this vulnerability is that it can be exploited to steal developers' API Keys via https://developer.mozilla.org/fr/users/account/keys as the page also allows cross-domain interactions. I have not tested it because I don't have any API Keys as it must be requested from Mozilla. But, the attack is easy to carry out I'll just have to modify the above PoC. Thanks
Requested API key (1207077) for testing on allizom.org domain
See Also: → bug 1207077
I don't see a risk of stealing account API keys via /users/account/keys. When a user generates an API key, we show it to them a single time/request at users/account/keys/new - it's never listed at /users/account/keys.
Thanks Luke

Marking bug as new, confirmed CSRF issue.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Restrictive ORIGIN headers are considered a strong CSRF defense on their own, while the existing wildcard headers weaken the use of a CSRF token. 

Luke, any idea how restrictively ORIGIN could be configured for MDN without breaking any expected functionality?
Flags: needinfo?(lcrouch)
:adamm - I know there are a number of sites/clients that use our endpoints to inline some MDN content. But I don't think we have any of our own clients that use it though.

I think we should favor security over the functionality of 3rd-party sites/clients relying on the open CORS. We can create an ALLOW list of domains that are approved to fetch MDN content across origins if we get requests to do so.
Flags: needinfo?(lcrouch)
Keywords: in-triage

Updated

2 years ago
Flags: needinfo?(jvehent)
We removed the site-wide wildcard CORS headers. [1] We selectively add the access-control-allow-origin: * header to only specific endpoints that may be useful for client scripts.

E.g., https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS provides a header while https://developer.mozilla.org/en-US/profiles/groovecoder/edit does not.

I audited to make sure we're not adding the header on any pages with a form, so an attacker should no longer be able to grab CSRF tokens via CORS.

Thanks for the bug report!

[1] https://github.com/mozilla/kuma/commit/f8df2a5f6b053b9da5a5a889de2fc8a4137c7170
Status: NEW → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → FIXED
This bug needs a security rating. Can either of you suggest one?
Flags: needinfo?(lcrouch)
Flags: needinfo?(amuntner)
(In reply to Luke Crouch [:groovecoder] from comment #8)
> We removed the site-wide wildcard CORS headers. [1] We selectively add the
> access-control-allow-origin: * header to only specific endpoints that may be
> useful for client scripts.

"*" is, in general, supposed to be a safe response as the browser does not allow any credentials (login cookies) to be used. If we're then returning a csrftoken on an unauthenticated page that can be used on an authenticated request then we're doing csrf tokens wrong.
Flags: needinfo?(yboily)
Flags: needinfo?(amuntner)
Keywords: in-triage → wsec-csrf
Keywords: wsec-disclosure
Keywords: sec-moderate
Flags: needinfo?(yboily)
Flags: sec-bounty? → sec-bounty+
For bugs that are resolved, we remove the security flag. These haven't had their flag removed, so I'm removing it now.
Group: websites-security
Flags: needinfo?(lcrouch)
You need to log in before you can comment on or make changes to this bug.