18.02.2013 Views

busting-frame-busting-a-study-of-clickjacking-vulnerabilities-on-popular-sites-slides

busting-frame-busting-a-study-of-clickjacking-vulnerabilities-on-popular-sites-slides

busting-frame-busting-a-study-of-clickjacking-vulnerabilities-on-popular-sites-slides

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

What is <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g>?


What is <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g>?<br />

• HTML allows for any site to <str<strong>on</strong>g>frame</str<strong>on</strong>g> any URL with an IFRAME<br />

(internal <str<strong>on</strong>g>frame</str<strong>on</strong>g>)<br />

<br />

Ignored by most browsers<br />


What is <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g>?<br />

• Frame <str<strong>on</strong>g>busting</str<strong>on</strong>g> are techniques for<br />

preventing framing by the <str<strong>on</strong>g>frame</str<strong>on</strong>g>d site.


What is <str<strong>on</strong>g>frame</str<strong>on</strong>g><str<strong>on</strong>g>busting</str<strong>on</strong>g>?<br />

Comm<strong>on</strong> <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g> code is made<br />

up <str<strong>on</strong>g>of</str<strong>on</strong>g>:<br />

• a c<strong>on</strong>diti<strong>on</strong>al statement<br />

• a counter acti<strong>on</strong><br />

if (top != self) {<br />

top.locati<strong>on</strong> = self.locati<strong>on</strong>;<br />

}


Why <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g>?


Primary: Clickjacking<br />

Jeremiah Grossman and Robert Hansen, 2008


Clickjacking 2.0<br />

(Paul St<strong>on</strong>e, BHEU ‘10)<br />

Utilizing drag and drop:<br />

Grab data <str<strong>on</strong>g>of</str<strong>on</strong>g>f the page<br />

(including source code, form data)<br />

Get data into the page<br />

(forms etc.)<br />

Fingerprint individual objects in the <str<strong>on</strong>g>frame</str<strong>on</strong>g>d<br />

page


Survey<br />

• Idea: Grab <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g> from Alexa<br />

Top-500 and all US banks.<br />

Analyze code.<br />

• Used semi-automated crawler based<br />

<strong>on</strong> HTMLUnit.<br />

• Manual work to trace through<br />

obfuscated and packed code.


Obfuscati<strong>on</strong>/Packing<br />


Survey<br />

Sites Frame<str<strong>on</strong>g>busting</str<strong>on</strong>g><br />

Top 10 60%<br />

Top 100 37%<br />

Top 500 14%


Survey<br />

C<strong>on</strong>diti<strong>on</strong>al Statements<br />

if (top != self)<br />

if (top.locati<strong>on</strong> != self.locati<strong>on</strong>)<br />

if (top.locati<strong>on</strong> != locati<strong>on</strong>)<br />

if (parent.<str<strong>on</strong>g>frame</str<strong>on</strong>g>s.length > 0)<br />

if (window != top)<br />

if (window.top !== window.self)<br />

if (window.self != window.top)<br />

if (parent && parent != window)<br />

if (parent &&<br />

parent.<str<strong>on</strong>g>frame</str<strong>on</strong>g>s &&<br />

parent.<str<strong>on</strong>g>frame</str<strong>on</strong>g>s.length>0)<br />

if((self.parent&&<br />

!(self.parent===self))&&<br />

(self.parent.<str<strong>on</strong>g>frame</str<strong>on</strong>g>s.length!=0))


Counter-Acti<strong>on</strong> Statements<br />

top.locati<strong>on</strong> = self.locati<strong>on</strong><br />

top.locati<strong>on</strong>.href = document.locati<strong>on</strong>.href<br />

top.locati<strong>on</strong>.href = self.locati<strong>on</strong>.href<br />

top.locati<strong>on</strong>.replace(self.locati<strong>on</strong>)<br />

top.locati<strong>on</strong>.href = window.locati<strong>on</strong>.href<br />

top.locati<strong>on</strong>.replace(document.locati<strong>on</strong>)<br />

top.locati<strong>on</strong>.href = window.locati<strong>on</strong>.href<br />

top.locati<strong>on</strong>.href = "URL"<br />

document.write(’’)<br />

top.locati<strong>on</strong> = locati<strong>on</strong><br />

top.locati<strong>on</strong>.replace(document.locati<strong>on</strong>)<br />

top.locati<strong>on</strong>.replace(’URL’)<br />

top.locati<strong>on</strong>.href = document.locati<strong>on</strong><br />

top.locati<strong>on</strong>.replace(window.locati<strong>on</strong>.href)<br />

top.locati<strong>on</strong>.href = locati<strong>on</strong>.href<br />

self.parent.locati<strong>on</strong> = document.locati<strong>on</strong><br />

parent.locati<strong>on</strong>.href = self.document.locati<strong>on</strong><br />

top.locati<strong>on</strong>.href = self.locati<strong>on</strong><br />

top.locati<strong>on</strong> = window.locati<strong>on</strong><br />

top.locati<strong>on</strong>.replace(window.locati<strong>on</strong>.pathname)<br />

window.top.locati<strong>on</strong> = window.self.locati<strong>on</strong><br />

setTimeout(functi<strong>on</strong>(){document.body.innerHTML=’’;},1);<br />

window.self.<strong>on</strong>load = functi<strong>on</strong>(evt){document.body.innerHTML=’’;}<br />

var url = window.locati<strong>on</strong>.href; top.locati<strong>on</strong>.replace(url)


All <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g> code we found<br />

was broken.


Let’s check out some code.


Courtesy <str<strong>on</strong>g>of</str<strong>on</strong>g> Walmart<br />

if (top.locati<strong>on</strong> != locati<strong>on</strong>) {<br />

}<br />

if(document.referrer &&<br />

document.referrer.indexOf("walmart.com") == -1)<br />

{<br />

}<br />

top.locati<strong>on</strong>.replace(document.locati<strong>on</strong>.href);


Error in Referrer Checking<br />

From http://www.attacker.com/walmart.com.html<br />

<br />

Limit use <str<strong>on</strong>g>of</str<strong>on</strong>g> indexOf()…


Courtesy <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

if (window.self != window.top &&<br />

{<br />

}<br />

!document.referrer.match(<br />

/https?:\/\/[^?\/]+\.nytimes\.com\//))<br />

self.locati<strong>on</strong> = top.locati<strong>on</strong>;


Error in Referrer Checking<br />

From http://www.attacker.com/a.html?b=https://www.nytimes.com/<br />

<br />

Anchor your regular expressi<strong>on</strong>s.


Courtesy <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

if (self != top) {<br />

}<br />

var domain = getDomain<br />

(document.referrer);<br />

var okDomains = /usbank|localhost|usbnet/;<br />

var matchDomain = domain.search<br />

(okDomains);<br />

if (matchDomain == -1) {<br />

}<br />

//<str<strong>on</strong>g>frame</str<strong>on</strong>g> bust


Error in Referrer Checking<br />

From http://usbank.attacker.com/<br />

<br />

D<strong>on</strong>’t make your regular expressi<strong>on</strong>s too lax.


Strategic Relati<strong>on</strong>ship?<br />

Norweigan State House Bank<br />

http://www.husbanken.no


Strategic Relati<strong>on</strong>ship?<br />

Bank <str<strong>on</strong>g>of</str<strong>on</strong>g> Moscow<br />

http://www.rusbank.org


Courtesy <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

try{<br />

A=!top.locati<strong>on</strong>.href<br />

}catch(B){}<br />

A=A&&<br />

!(document.referrer.match(/^https?:\/\/[-az09.]<br />

*\.google\.(co\.|com\.)? [a-z] +\/imgres/i))&&<br />

!(document.referrer.match(/^https?:\/\/([^\/]*\.)?<br />

(myspace\.com|<br />

myspace\.cn|<br />

simsidekick\.com|<br />

levisawards\.com|<br />

digg\.com)\//i));<br />

if(A){ //Framebust }


The people you trust might not<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g> bust<br />

Google Images does not <str<strong>on</strong>g>frame</str<strong>on</strong>g>bust.


Referrer = Funky Stuff<br />

Many attacks <strong>on</strong> referrer: washing/changing<br />

Open redirect referrer changer<br />

HTTPS->HTTP washing<br />

Can be hard to get regular expressi<strong>on</strong> right<br />

(apparently)<br />

“Friends” cannot be trusted


Facebook Dark Layer


Courtesy <str<strong>on</strong>g>of</str<strong>on</strong>g> Facebook<br />

• Facebook deploys an exotic variant:<br />

if (top != self) {<br />

try {<br />

if (top.locati<strong>on</strong>.hostname.indexOf("apps") >= 0) throw 1;<br />

} catch (e) {<br />

window.document.write("<br />

");<br />

}<br />

}


Facebook – Ray <str<strong>on</strong>g>of</str<strong>on</strong>g> Light!<br />

All Facebook c<strong>on</strong>tent is centered! We can<br />

push the c<strong>on</strong>tent into the ray <str<strong>on</strong>g>of</str<strong>on</strong>g> light<br />

outside <str<strong>on</strong>g>of</str<strong>on</strong>g> the div.<br />

<br />

<br />

window.scrollTo(10200, 0 ) ;<br />


Facebook – Ray <str<strong>on</strong>g>of</str<strong>on</strong>g> Light!


Let’s move <strong>on</strong> to some<br />

generic attacks!


Courtesy <str<strong>on</strong>g>of</str<strong>on</strong>g> many<br />

if(top.locati<strong>on</strong> != self.locati<strong>on</strong>) {<br />

}<br />

parent.locati<strong>on</strong> = self.locati<strong>on</strong>;


Double Framing!<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g>d1.html<br />

<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g>d2.html<br />


Descendent Policy<br />

• Introduced in Securing <str<strong>on</strong>g>frame</str<strong>on</strong>g> communicati<strong>on</strong> in browsers.<br />

(Adam Barth, Collin Jacks<strong>on</strong>, and John Mitchell. 2009)<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g>d1.html<br />

<br />

Descendant Policy<br />

A <str<strong>on</strong>g>frame</str<strong>on</strong>g> can navigate <strong>on</strong>ly it’s decedents.<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g>d2.html<br />

top.locati<strong>on</strong> = self.locati<strong>on</strong> is always okay.<br />


Locati<strong>on</strong> Clobbering<br />

if (top.locati<strong>on</strong> != self.locati<strong>on</strong>) {<br />

}<br />

top.locati<strong>on</strong> = self.locati<strong>on</strong>;<br />

If top.locati<strong>on</strong> can be changed or<br />

disabled this code is useless.<br />

But our trusted browser would never let<br />

such atrocities happen… right?


Locati<strong>on</strong> Clobbering<br />

IE 7: IE 7:<br />

var locati<strong>on</strong> = “clobbered”;<br />

Safari:<br />

window.__defineSetter__("locati<strong>on</strong>", functi<strong>on</strong>(){});<br />

top.locati<strong>on</strong> is now undefined. �<br />

http://code.google.com/p/ browsersec/wiki/Part2#Arbitrary_ page_mashups_(UI_redressing)


Asking Nicely<br />

• User can manually cancel any<br />

redirecti<strong>on</strong> attempt made by<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g><str<strong>on</strong>g>busting</str<strong>on</strong>g> code.<br />

• Attacker just needs to ask…<br />

<br />

window.<strong>on</strong>beforeunload = functi<strong>on</strong>() {<br />

}<br />

return ”Do you want to leave PayPal?";<br />

<br />


Asking Nicely


Not Asking Nicely<br />

• Actually, we d<strong>on</strong>’t have to ask nicely<br />

at all. Most browser allows to cancel<br />

the relocati<strong>on</strong> “programmatically”.<br />

var prevent_bust = 0<br />

window.<strong>on</strong>beforeunload = functi<strong>on</strong>() {kill_bust++ }<br />

setInterval(functi<strong>on</strong>() {<br />

if (kill_bust > 0) {<br />

kill_bust -= 2;<br />

}<br />

}, 1);<br />

window.top.locati<strong>on</strong> = 'http://no-c<strong>on</strong>tent-204.com'<br />

<br />

http://coderrr.wordpress.com/2009/02/13/preventing-<str<strong>on</strong>g>frame</str<strong>on</strong>g>-<str<strong>on</strong>g>busting</str<strong>on</strong>g>-and-click-jacking-ui-redressing


• IE 8:<br />

Restricted z<strong>on</strong>es<br />

<br />

Javascript and Cookies disabled<br />

• Chrome (HTML5):<br />

<br />

Javascript disabled (cookies still there)<br />

• IE 8 and Firefox:<br />

designMode = <strong>on</strong> (Paul St<strong>on</strong>e BHEU’10)<br />

Javascript disabled (more cookies)


Reflective XSS filters<br />

• Internet Explorer 8 introduced reflective<br />

XSS filters:<br />

http://www.victim.com?var= alert(‘xss’)<br />

If alert(‘xss’); appears in the rendered<br />

page, the filter will replace it with alert<br />

(‘xss’)


Reflective XSS filters<br />

Can be used to target <str<strong>on</strong>g>frame</str<strong>on</strong>g> <str<strong>on</strong>g>busting</str<strong>on</strong>g><br />

(Eduardo Vela ’09)<br />

Original<br />

if(top.locati<strong>on</strong> != self.locati<strong>on</strong>) //<str<strong>on</strong>g>frame</str<strong>on</strong>g>bust <br />

Request > http://www.victim.com?var= if (top<br />

Rendered<br />

if(top.locati<strong>on</strong> != self.locati<strong>on</strong>)<br />

Chrome’s XSS auditor, same problem.


Is there any hope?<br />

Well, sort <str<strong>on</strong>g>of</str<strong>on</strong>g>…


X-Frames-Opti<strong>on</strong>s (IE8)<br />

• HTTP header sent <strong>on</strong> resp<strong>on</strong>ses<br />

• Two possible values: DENY and<br />

SAMEORIGIN<br />

• On DENY, will not render in <str<strong>on</strong>g>frame</str<strong>on</strong>g>d<br />

c<strong>on</strong>text.<br />

• On SAMEORIGIN, <strong>on</strong>ly render if top<br />

<str<strong>on</strong>g>frame</str<strong>on</strong>g> is same origin as page giving<br />

directive.


X-Frames-Opti<strong>on</strong>s<br />

• Good adopti<strong>on</strong> by browsers (all but<br />

Firefox, coming in 3.7)<br />

• Poor adopti<strong>on</strong> by <strong>sites</strong> (4 out <str<strong>on</strong>g>of</str<strong>on</strong>g> top<br />

10,000, survey by sans.org)<br />

• Some limitati<strong>on</strong>s: per-page policy, no<br />

whitelisting, and proxy problems.


C<strong>on</strong>tent Security Policy (FF)<br />

• Also a HTTP-Header.<br />

• Allows the site to specific restricti<strong>on</strong>s/<br />

abilities.<br />

• The <str<strong>on</strong>g>frame</str<strong>on</strong>g>-ancestors directive can<br />

specifiy allowed <str<strong>on</strong>g>frame</str<strong>on</strong>g>rs.<br />

• Still in beta, coming in Firefox 3.7


Best for now<br />

(but still not good)<br />

html { visibility: hidden }<br />

<br />

if (self == top) {<br />

document.documentElement.style.visibility =<br />

'visible';<br />

} else {<br />

}<br />

top.locati<strong>on</strong> = self.locati<strong>on</strong>;<br />


… a little bit more.<br />

These <strong>sites</strong> (am<strong>on</strong>g others) do <str<strong>on</strong>g>frame</str<strong>on</strong>g>m<str<strong>on</strong>g>busting</str<strong>on</strong>g>…


… a little bit more.<br />

… but do these?


No, they generally d<strong>on</strong>’t…<br />

Site URL Frame<str<strong>on</strong>g>busting</str<strong>on</strong>g><br />

Facebook http://m.facebook.com/ YES<br />

MSN http://home.mobile.msn.com/ NO<br />

GMail http://m.gmail.com NO<br />

Baidu http://m.baidu.com NO<br />

Twitter http://mobile.twitter.com NO<br />

MegaVideo http://mobile.megavideo.com/ NO<br />

Tube8 http://m.tube8.com NO<br />

PayPal http://mobile.paypal.com NO<br />

USBank http://mobile.usbank.com NO<br />

First Interstate Bank http://firstinterstate.mobi NO<br />

NewEgg http://m.newegg.com/ NO<br />

MetaCafe http://m.metacafe.com/ NO<br />

RenRen http://m.renren.com/ NO<br />

MySpace http://m.myspace.com NO<br />

VK<strong>on</strong>takte http://pda.vk<strong>on</strong>takte.ru/ NO<br />

WellsFargo https://m.wf.com/ NO<br />

NyTimes http://m.nytimes.com Redirect<br />

E-Zine Articles http://m.ezinearticles.com Redirect


Summary<br />

• All <str<strong>on</strong>g>frame</str<strong>on</strong>g><str<strong>on</strong>g>busting</str<strong>on</strong>g> code out there can<br />

be broken across browsers in several<br />

different ways<br />

• Defenses are <strong>on</strong> the way, but not yet<br />

widely adopted<br />

• Relying <strong>on</strong> referrer is difficult<br />

• If JS is disabled, d<strong>on</strong>’t render the page.<br />

• Framebust your mobile <strong>sites</strong>!


Questi<strong>on</strong>s?<br />

rydstedt@stanford.edu

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!