Back in October, I found a couple of issues in Etsy, which when combined could be used in a click-jacking attack.
Incorrect Error Handling
Pretty much all forms on Etsy have a token attached to prevent CSRF attacks. Failing to provide, or providing an incorrect token will result in the form not being processed, and an error page will be displayed.
If we submit a POST to the search page, the request is (correctly) not processed. But, rather than showing the generic error page, we get the homepage instead.
This isn’t that interesting, nor very useful. However, this combined with…
Bypassing X-Frame-Options with a Referrer
The value of the X-Frame-Options header across Etsy is SAMEORIGIN, meaning that only pages from the same domain will load in a frame, else a blank screen is displayed, thus thwarting click-jacking attacks.
The value of the Referer header is checked, and if the domain is etsy.com, the response back is ALLOW, rather than SAMEORIGIN. Luckily, in the previous issue, when the homepage is returned, no X-Frame-Options header is sent!
So now that we can successfully frame the home-page, all we need to do is get a user to click links on the framed page, and we have a way of framing any page on the site.
Of course, this requires a user to click multiple times (since there isn’t any sensitive actions that can be performed with one click on the homepage). The best way is to turn it into some sort-of game (my creativity is lacking, hence the simplicity).
We use setTimeout to change the position of the iframe after a x seconds (to give the page enough time to load), and entice the user to click the stopwatch (which contains each link underneath).
We use the pointer-events: none; CSS value to pass the click through the image and to the link.
The user has now successfully deleted their wedding registry! Ouch.
Regrettably I didn’t take any screenshots when I reported this issue, and now that it’s fixed my only option is to photoshop them (which I won’t do). So you’ll have to take my word for some of it.
The fix was done in two stages. Firstly, the CSRF token was removed from the search form, presumably because there aren’t any modifications being made to user data, so it’s pointless. Secondly, the referrer checking was removed and SAMEORIGIN was enforced across all pages.
The second fix took longer to deploy, presumably due to the scale and amounts of testing required.