X-Frame-Options (XFO) Detection from Javascript

X-Frame-Options (XFO) is an HTTP response header, mostly used to combat Clickjacking, that informs a Web browser if the page should be rendered in a <* frame> or <* iframe>. “X-Frame-Options: deny” means that the browser should never allow the page to be framed. “X-Frame-Options: sameorigin” means only the hosting domain is allowed to frame the page.  In either case, a third-party website is never allowed to frame the page. No frames, no Clickjacking.

There are certain circumstances where it is useful for an attacker to know if an iFrame is being blocked by XFO from within Javascript space. For example, I was recently improving upon some Javascript cross-domain login detection code. I noticed a particular URL had a interesting boolean state. When a user is logged-in, no XFO header is sent. When the use was NOT logged-in, a login screen would appear, and of course an XFO header was there to protect it. So, if I could tell XFOs existence, I’d have yet another technique to perform cross-domain login checks.

I noticed that iFrames do not fire OnLoad event handlers, and why would they? We can use this behavior to test for the existence of XFO headers. To do so we create an iFrame, set the OnLoad functionality to immediately remove the iFrame from the DOM, and then use a setTimeout to check for its existence a few seconds later. If the iFrame still exists, this likely means an XFO was present which prevented the iFrame removal (via the OnLoad). Simple.

Proof-of-Concept code is below and RSnake was kind enough to host a live demo. You’ll have to suffer through my non-standard Javascript, I’ve recently been learning Dojo Toolkit. Enjoy!

<* script src=”http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js”><* /script>
<* script>

var urls = [
‘http://www.wikipedia.org/’,
‘http://ha.ckers.org/’,
‘http://www.google.com/’,
‘http://www.facebook.com/’,
‘https://github.com/’,
‘http://daringfireball.net/’,
];

function detect() {
dojo.forEach(urls, function(url) {
var iframe = dojo.create(“iframe”, { src: url, id: url });
dojo.attr(iframe, “style”, {display: ‘none’});

dojo.connect(iframe, “onload”, function() {
dojo.destroy(iframe);
});

dojo.place(iframe, dojo.body());

setTimeout(function () {
var obj = dojo.byId(url);
if (obj) {
dojo.destroy(iframe);
var entry = dojo.create(“li”, null, dojo.body());
entry.innerHTML = “Yes: ” + url;
} else {
var entry = dojo.create(“li”, null, dojo.body());
entry.innerHTML = “No: ” + url;
}
}, 3000);

});
}
<* /script>

 

 

 

 

 

This entry was posted in Technical Insight on by .

About Jeremiah Grossman

Jeremiah Grossman is the Founder and interim CEO of WhiteHat Security, where he is responsible for Web security R&D and industry outreach. Over the last decade, Mr. Grossman has written dozens of articles, white papers, and is a published author. His work has been featured in the Wall Street Journal, Forbes, NY Times and hundreds of other media outlets around the world. As a well-known security expert and industry veteran, Mr. Grossman has been a guest speaker on six continents at hundreds of events including TED, BlackHat Briefings, RSA, SANS, and others. He has been invited to guest lecture at top universities such as UC Berkeley, Stanford, Harvard, UoW Madison, and UCLA. Mr. Grossman is also a co-founder of the Web Application Security Consortium (WASC) and previously named one of InfoWorld's Top 25 CTOs. He serves on the advisory board of two hot start-ups, Risk I/O and SD Elements, and is a Brazilian Jiu-Jitsu Black Belt. Before founding WhiteHat, Mr. Grossman was an information security officer at Yahoo!