Clickjacking your Paypal account

Of course, compared to other attack vectors the threat imposed by Clickjacking is rather low. Right? … Not quite. Clickjacking can be a scary beast, which the following attack depicts.
Paypal recently launched a facebook app to send money to your Facebook friends. The app is embedded via an iframe in the usual Facebook UI and the whole process of sending money happens within the Facebook UI … or should at least.

How it takes place

The app is located at http://apps.paypal-sendmoney.com/paypal_sendmoney. It seems like the developers were aware of Clickjacking and deployed some defenses. Opening the URL directly in the address bar yields a 302 HTTP status code and forwards to http://apps.facebook.com/paypal_sendmoney/. So it’s not as easy as putting the URL in an iframe’s src-attribute. Let’s see how Facebook delivers the app:

Facebook inserts a token called signed_request and delivers everything to the client. As you can see from the markup above a form is utilized to send a POST request to http://apps.paypal-sendmoney.com/paypal_sendmoney and the response is loaded into an iframe. Note that the token signed_request is send along with the request. Depending on the value of signed_request the app’s web server decides whether to send the actual app or forward to http://apps.facebook.com/paypal_sendmoney. This should prevent framing from untrusted third parties.

And here is the vulnerability: There is no check if the user who’s requesting the token from Facebook is the same as the one requesting the actual app using the token. An attacker can request the token from Facebook, extract it and let another user request the app using the previously loaded token. Thus, the attacker is able to embed the app in an iframe and doing some tricky Clickjacking stuff. I’ve implemented a PoC, have a look here:

The attack works with any browser. The user has to be logged in to Facebook and the sendmoney app.

What’s now?

One might say “Ok, it’s a bug, just fix it” but this scenario shows the limitations of current client-side defenses against Clickjacking (see X-Frame-Options and Framebusting). Those defenses deny framing from foreign origins completely, but in this case certain pages should be able to frame while others are not. Paypal doesn’t have any other choice as coming up with a custom server-side solution like the one shown here. And, as often with custom solutions involving multiple parties, they are error-prone. Clickjacking takes place in the user’s browser, and I think this is where it should be circumvented. To fend of Clickjacking a standardized client-side mechanism is needed that allows to whitelist certain origins (and by the way: reducing clickjacking to invisible iframes doesn’t work, see here and here). To date, there is no such mechanism but new drafts of the HTTP Header Frame-Origin and From-Origin Header are looking promising.

The vulnerability was reported to PayPal and is fixed.

2 thoughts on “Clickjacking your Paypal account

  1. Good find!

    About the signed_request token: There’s one thing that’s bothering me – was it used for authenticating the request? After all, if the token is generated for the attacker, with attacker’s credentials, handing it off to the victim would only allow the victim to act as the attacker (and charge attacker’s Paypal). That’s the logical approach of generating tokens.

    Unless tokens were not tied to any credentials and were just used to authorize any request for the currently logged in user, whoever he is. But that’s weird, and a serious vuln indeed.

  2. Hey, thanks for the question. The victim is acting in his own authorization context and the token is not checked against any user. As you already said … it’s weird.

    You are totally right in describing how it should work … but actually the implementation works different. The token is not used to authenticate the user. Instead they try to use it to ensure that the request was issued by facebook, since only facebook can create valid tokens (one part of the token is a HMAC and the key for generating those is only known to Facebook, see http://developers.facebook.com/docs/authentication/signed_request/).

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>