Vulnerability Type: Broken Authorisation and missing CSRF In Paypal
Description: In https://www.paypalgivingfund.org website, every account is linked to an email address (which is normal). There is this option that you can use to change the email address that is linked to your email account. This how the process goes. If my current email address is email@example.com and I would like to change this address to firstname.lastname@example.org. When I add email@example.com as my new email address, the application sends a confirmation mail to the old email address which in this case is “firstname.lastname@example.org”. I should check the old email address and authorise the process to change to the new address.
The first question I had in my mind is whether this token is randomly generated or dependant on the email. To test that I did the following: I requested to change the email of the account to email@example.com and I received token. Let’s say the token was “somerandomvalue123123” << (remember it). I then made another request and I checked my email again. I was hoping to see the same old token again. Indeed, it was the same old one. This means that every email address, that you want to change to, has a static authorisation code. To be more technical the function signature should look similar to the following
The generate function does some scrambling to get the token, but it is completely deterministic one. For every email there is a unique token. That is a very bad technique in designing authorisation token. Why? We will see in a moment
What I want to do is to takeover the account of the target. How I can do that? I will try to trick the target to change the email address of his account to my email address. I want the user first to issue the change request with my email address. After that I want the user to approve this change! That seems very difficult, the user won’t do that.
Here it comes the other vulnerabilities. The “issue request” used to issue the change of the email address is vulnerable to CSRF. I can exploit the vulnerability and the user would send this request easily. Now, I want the user to approve/authenticate this change! Well, the link to approve the change is also vulnerable to CSRF vulnerability. But wait, it contains the authentication token which I don’t know!
That’s true. However, I just showed that every email address has a unique authorisation token. Remember the random token above “somerandomvalue123123“, it will be the same token generated when the user tries to reset his email to “firstname.lastname@example.org”. This means we can create the request and since the request is vulnerable to CSRF too, we can just force the attacker to click on it.
Impact: Full account take over
Update: Code I used can be found here: http://pastie.org/private/ilv0iwqgv4gekejkiwx3ga
PS: I wrote the write up in a hurry :(. You might find a lot of problems there! 🙁