Having problems with your account or logging in?
A lot of changes are happening in the community right now. Some may affect you. READ MORE HERE

Cross-frame scripting protection: A case of doing it wrong

SasiSiddharth Absent Member.
Absent Member.
0 0 17.3K

I recently came across a cross-frame scripting finding reported by WebInspect that was perceived to be a false positive. However, while analyzing it, I realized that the application was vulnerable and that it was a true positive finding. I also made an interesting observation in the way the application was trying to protect itself against the vulnerability, or lack thereof.

 

To give a brief introduction, the cross-frame scripting vulnerability allows a vulnerable application’s page to be included within an iframe of a malicious website. This allows for exploits such as clickjacking and frame sniffing. The recommended protection against such exploits is to use the X-Frame Options response header and include a JavaScript snippet that performs frame-busting. While the use of declarative security headers is the best protection mechanism, complementing it with frame-busting helps protect users on older versions of a web browser.

Frame-busting logic usually looks similar to the following code snippet.

 

if(top != self)
{
   location = self.location;
} 

 

 Now, I came across the following snippet in one of the samples.

(1) <script type="text/javascript" src="/js/jquery/jquery_1_6_4.js"/>
(2) <style> html{display:none;} </style>
(3) <script type="text/javascript">
(4)    if(self == top) { document.documentElement.style.display = 'block'; }
(5)    else { top.location = self.location; }
(6) </script>

 

 At first glance, this code snippet seems correct. However, in reality, it failed to protect the application from the cross-frame scripting attack. A closer look revealed an interesting concept that could easily be overlooked by web developers. Let’s analyze this snippet line-by-line.

 

Line 1 is used to include an external script file into the current Document Object Model (DOM). Line 2 provides a style construct that hides the entire DOM by default. Lines 3 to 6 contain the next script block that decides whether or not to unhide the DOM. Looking deeper into this block, line 4 tests whether the page is embedded within an iframe. If not, it displays the DOM on the browser. Line 5 is executed if the current page is embedded within an iframe. In this case, it breaks out of the frame and reloads the page.

 

The flaw in this code happens to be in line 1. The script tag in line 1 has been self-closed. According to the HTML specification, void elements are defined as HTML elements/tags that can be self-closed. The following elements are listed as valid void elements – area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr. The specification varies between HTML5, HTML4 and XHTML. I’m focusing primarily on the HTML4 specification since it’s widely used. Also, while HTML5 makes some closing tags completely optional, it is still recommended to continue using them in order to improve code readability.

 

Since the script tag isn’t a void element, a self-closed script tag cannot be recognized by a browser. Hence, the browser tries to process lines 1-6 as a single script block, but fails to execute it since line 2 is not valid JavaScript. This results in the frame-busting snippet not working as expected.

 

If this script block had contained code that affected the application’s functionality, it would have probably been discovered by the QA team. But frame-busting code isn’t usually considered to be part of the actual application, and hence could easily slip through the cracks (such as the one I examined) unless a vulnerability assessment is conducted.

 

The main takeaway here is to be aware of such details and quirks in the HTML specification and to understand that while browsers try to self-correct some HTML issues, they might not always be predictable and clearly that can result in security implications for a web application.

The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.