Where was the Hacker in the Room for X-FRAME-OPTIONs?
November 13, 2009 Leave a comment
Update: don’t worry, they took care of it – but as of Feb 2012 only IE: http://blogs.msdn.com/b/ieinternals/archive/2010/03/30/combating-clickjacking-with-x-frame-options.aspx
Or maybe where was the Dev in the room?
Imagine you’re sitting at a computer logged into your favorite website, lolcats, and you click on a shady link while logged in. There are a lot of attack scenarios that start this way.
Browsers have a cross domain policy that prevent the shady site from accessing any of your lolcats cookies, which typically contain your authentication tokens. But BY DESIGN, the shady site is certainly allowed to do requests (eg POST or GET) across domains. So there’s nothing to prevent the shady site from framing lolcats in an invisible iframe and having you play an animated whack-a-mole game, clicking exactly where the invisible lolcats site is having you inadvertently rank the attacker’s disgusting kitten as cute. This is performed with your very own account, because the cookies are all legitimate from being logged in. This makes all your lolcats buddies laugh at your bad taste.
Currently clickjacking defense is treated somewhat less importantly than XSRFf, but the fact is, the surface area for a clickjacking attack is basically identical to XSRF. Both are confused deputy problems.
So there is only one defense that really works to defend against clickjacking, and this is X-FRAME-OPTIONs. X-FRAME-OPTIONs is a newish header designed by Microsoft that’s now included in all modern browsers (chrome, Firefox, Safari, in addition to IE8 and IE9). What X-FRAME-OPTIONs does is set a header that says this response cannot be framed except under certain circumstances. There does need to be work on server applications to add this header, but I believe this is fundamentally the right approach to stop clickjacking. You don’t want lolcats framed by the shady site? Just configure lolcats to put the X-FRAME-OPTIONs header in the response and it cannot be framed.
Here’s the problem, X-FRAME-OPTIONs has three options: ALLOW, SAMEORIGIN, and DENY. That’s it. And they do exactly what you’d think they do.
What if, by design, I want my application to be framed by something in a different domain? There are a lot of legitimate circumstances this happens, and they pop up all the time in Online Services.
As a security industry, what we do right now in these situations is say there’s no good and easy defense. Web applications are sometimes vulnerable to clickjacking because the fact is there’s nothing good we can really do on these edge case scenarios. We can (and do) develop frame busting scripts that takes a lot of work, probably have holes, and are certainly bypassible in IE8 and IE9 due to the XSS protection unless we just explicitly switch off the XSS protection. It’s an active problem to determine if switching off XSS protection in order to hopefully develop a script that might with enough effort prevent clickjacking is worth it.
I wonder why when designing X-FRAME-OPTIONs it wasn’t just designed as a whitelist solution. Instead of only having the ALLOW, SAMEORIGIN, and DENY options, it could have a list of domains that are allowed to frame the content. It would make so much more sense to explicitly allow domains that are allowed to frame our application instead of being arbitrarily restricted to sameorigin. It would give us flexibility while at the same time allowing us to be safe.
I applaud the IE team for coming up with X-FRAME-OPTIONs in the first place, and for other browsers to adopt it. It can protect 95% of sites from clickjacking. I just wish that we didn’t have to have vulnerable sections of applications just because of the limitation of options.