Testing for Clickjacking (OTG-CLIENT-009)

Brief Summary
"Clickjacking" (that is a subset of the "UI redressing") is a malicious technique that consists of deceiving a web user into interact (in most cases by clicking) on something different to what the user believes he is interacting on. This type of attack, that can be used alone or in combination with other attacks, could potentially send unauthorized commands or reveal confidential information while the victim is interacting on seemingly harmless web pages. The term "Clickjacking" was coined by Jeremiah Grossman and Robert Hansen in 2008.

Description of the Issue
A Clickjacking attack uses seemingly innocuous features of HTML and Javascript to force the victim to perform undesired actions, such as clicking on a button that appears to perform another operation. This is a "client side" security issue that affects a variety of browsers and platforms. To carry out this type of technique the attacker has to create a seemingly harmless web page that loads the target application throught the use of an iframe (suitably concealed through the use of CSS code). Once this is done, the attacker could induce the victim to interact with his fictitious web page by other means (like for example social engineering). Like others attacks, an usual prerequisite is that the victim is authenticated against the attacker's target website.



Once the victim is surfing on the fictitious web page, he thinks that he is interacting with the visible user interface, but effectively he is performing actions on the hidden page. Since the hidden page is an authentic page, the attacker can deceive users into performing actions which they never intended to perform through an "ad hoc" positioning of the elements in the web page.



The power of this method is due to the fact that the actions performed by the victim are originated from the authentic target web page (hidden but authentic). Consequently some of the anti-CSRF protections, that are deployed by the developers to protect the web page from CSRF attacks, could be bypassed.

Black Box testing and example
Blackbox testing for Clickjacking is not usually performed since access to the source code is always available as it needs to be sent to the client to be executed.

Testing for Clickjacking vulnerabilities:
As mentioned above, this type of attack is often designed to allow an attacker site to induce user's actions on the target site even if anti-CSRF tokens are being used. So it's important, like for the CSRF attack, to individuate web pages of the target site that it take input from the user. We have to discover if the website that we are testing has no protections against clickjacking attacks or, if the developers have implemented some forms of protection, if these techniques are liable to bypass. Once we know that the website is vulnerable, we can create a "proof of concept" to exploit the vulnerability. The first step to discover if a website is vulnerable, is to check if the target web page could be loaded into an iframe. To do this you need to create a simple web page that includes a frame containing the target web page. The HTML code to create this testing web page is displayed in the following snippet:

Clickjack test page Website is vulnerable to clickjacking! 

Result Expected: If you can see both the text "Website is vulnerable to clickjacking!" at the top of the page and your target web page successfully loaded into the frame, then your site is vulnerable and has no type of protection against Clickjacking attacks. Now you can directly create a "proof of concept" to demonstrate that an attacker could exploit this vulnerability.

Bypass Clickjacking protection:
In case in which you only see the target site or the text "Website is vulnerable to clickjacking!" but nothing in the iframe this mean that the target probably has some form of protection against clickjacking. It’s important to note that this isn’t a guarantee that the page is totally immune to clickjacking. Methods to protect a web page from clickjacking can be divided in two macro-categories: In some circumstances, every single type of defense could be bypassed. Following are presented the main methods of protection from these attacks and techniques to bypass them.
 * Client side protection: Frame Busting
 * Server side protection: X-Frame-Options

Client side protection: Frame Busting
The most common client side method, that has been developed to protect a web page from clickjacking, is called Frame Busting and it consists of a script in each page that should not be framed. The aim of this technique is to prevent a site from functioning when it is loaded inside a frame. The structure of frame busting code typically consists of a "conditional statement" and a "counter-action" statement. For this type of protection, there are some circumventions that fall under the name of "Bust frame busting". Some of this techniques are browser-specific while others work across browsers.

Mobile website version Mobile versions of the website are usually smaller and faster than the desktop ones, and they have to be less complex than the main application. Mobile variants have often less protection since there is the wrong assumption that an attacker could not attack an application by the smarthphone. This is fundamentally wrong, because an attacker can fake the real origin given by a web browser, such that a non-mobile victim may be able to visit an application made for mobile users. From this assumption follows that in some cases it is not necessary to use techniques to evade frame busting when there are unprotected alternatives, which allow the use of same attack vectors.

Double Framing Some frame busting techniques try to break frame by assigning a value to the "parent.location" attribute in the "counter-action" statement. Such actions are, for example: This method works well until the target page is framed by a single page. However, if the attacker encloses the target web page in one frame which is nested in another one (a double frame), then trying to access to "parent.location" becomes a security violation in all popular browsers, due to the descendant frame navigation policy. This security violation disables the counter-action navigation. Target site frame busting code (target site):
 * self.parent.location = document.location
 * parent.location.href = self.location
 * parent.location = self.location

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

Attacker’s top frame (fictitious2.html): 

Attacker’s fictitious sub-frame (fictitious.html): 

Disabling javascript Since these type of client side protections relies on JavaScript frame busting code, if the victim has JavaScript disabled or it is possible for an attacker to disable JavaScript code, the web page will not have any protection mechanism against clickjacking. There are three deactivation techniques that can be used with frames: Example:  Example: 
 * Restricted frames with Internet Explorer: Starting from Internet Explorer 6, a frame can have the "security" attribute that, if it is set to the value "restricted", ensures that JavaScript code, ActiveX controls, and re-directs to other sites do not work in the frame.
 * Sandbox attribute: with HTML5 there is a new attribute called "sandbox". It enables a set of restrictions on content loaded into the iframe. At this moment this attribute is only compatible whit Chrome and Safari.
 * Design mode: Paul Stone showed a security issue concerning the "designMode" that can be turned on in the framing page (via document.designMode), disabling JavaScript in top and sub-frame. The design mode is currently implemented in Firefox and IE8.

onBeforeUnload event The onBeforeUnload event could be used to evade frame busting code. This event is called when the frame busting code wants to destroy the iframe by loading the URL in the whole web page and not only in the iframe. The handler function returns a string that is prompted to the user asking confirm if he wants to leave the page. When this string is displayed to the user is likely to cancel the navigation, defeating traget's frame busting attempt. The attacker can use this attack by registering an unload event on the top page using the following example code:

www.fictitious.site window.onbeforeunload = function {     return " Do you want to leave fictitious.site?"; } 

The previous technique requires the user interaction but, the same result, can be achieved without prompting the user. To do this the attacker have to automatically cancel the incoming navigation request in an onBeforeUnload event handler by repeatedly submitting (for example every millisecond) a navigation request to a web page that responds with a "HTTP/1.1 204 No Content" header. Since with this response the browser will do nothing, the resulting of this operation is the flushing of the request pipeline, rendering the original frame busting attempt futile. Following an example code:

204 page: 

Attacker's page: var prevent_bust = 0; window.onbeforeunload = function { prevent_bust++; };	setInterval(		function {			if (prevent_bust > 0) {				prevent_bust -= 2;				window.top.location = "http://attacker.site/204.php";			}		}, 1); 

XSS Filter Starting from Google Chrome 4.0 and from IE8 there were introduced XSS filters to protect users from reflected XSS attacks. Nava and Lindsay have observed that these kind of filters can be used to deactivate frame busting code by faking it as malicious code. Example: Target web page frame busting code: if ( top != self ) {     top.location=self.location; } Attacker code: 
 * IE8 XSS filter: this filter has visibility into all requests and responses parameters flowing through the web browser and it compares them to a set of regular expressions in order to look for reflected XSS attempts. When the filter identifies a possible XSS attacks; it disable all inline scripts within the page, including frame busting scripts (the same thing could be done with external scripts). For this reason an attacker could induces a false positive by inserting the beginning of the frame busting script into a request parameters.

Example:
 * Chrome 4.0 XSSAuditor filter: It has a little different behaviour compared to IE8 XSS filter, in fact with this filter an attacker could deactivate a "script" by passing its code in a request parameter. This enables the framing page to specifically target a single snippet containing the frame busting code, leaving all the other codes intact.

Target web page frame busting code: if ( top != self ) {     top.location=self.location; }

Attacker code: 

Redefining location For several browser the "document.location" variable is an immutable attribute. However, for some version of Internet Explorer and Safari, it is possible to redefine this attribute. This fact can be exploited to evade frame busting code. Example: var location = "xyz";  Example: window.defineSetter("location", function{}); 
 * Redefining location in IE7 and IE8: it is possible to redefine "location" as it is illustrated in the following example. By defining "location" as a variable, any code that tries to read or to navigate by assigning "top.location" will fail due to a security violation and so the frame busting code is suspended.
 * Redefining location in Safari 4.0.4: To bust frame busting code with "top.location" it is possible to bind "location" to a function via defineSetter (through window), so that an attempt to read or navigate to the "top.location" will fail.

Server side protection: X-Frame-Options
An alternative approach to client side frame busting code was implemented by Microsoft and it consists of an header based defense. This new "X-FRAME-OPTIONS" header is sent from the server on HTTP responses and is used to mark web pages that shouldn't be framed. The "X-FRAME-OPTIONS" is a very good solution, and was adopted by major browser, but also for this technique there are some limitations that could lead in any case to exploit the clickjacking vulnerability.

Browser compatibility Since the "X-FRAME-OPTIONS" was introduced in 2009, this header is not compatible with old browser. So every user that doesn't have an updated browser could be victim of clickjacking attack.

Proxies Web proxies are known for adding and stripping headers. In the case in which a web proxy strips the "X-FRAME-OPTIONS" header then the site loses its framing protection.

Mobile website version Also in this case, since the "X-FRAME-OPTIONS" has to be implemented in every page of the website, the developers may have not protected the mobile version of the website.

Create a "proof of concept"
Once we have discovered that the site we are testing is vulnerable to clickjacking attack, we can proceed with the development of a "proof of concept" to demonstrate the vulnerability. It is important to note that, as mentioned previously, these attacks can be used in conjunction with other forms of attacks (for example CSRF attacks) and could lead to overcome anti-CSRF tokens. In this regard we can imagine that, for example, the target site allows to authenticated and authorized users to make a transfer of money to another account. Suppose that to execute the transfer the developers have planned three steps. In the first step the user fill a form with the destination account and the amount. In the second step, whenever the user submits the form, is presented a summary page asking the user confirmation (like the one presented in the following picture).



Following a snippet of the code for the step 2:

//generate random anti CSRF token $csrfToken = md5(uniqid(rand, TRUE));

//set the token as in the session data $_SESSION['antiCsrf'] = $csrfToken;

//Transfer form with the hidden field $form = '  BANK XYZ - Confirm Transfer Do You want to confirm a transfer of . $_REQUEST['amount'] .' &euro; to account: '. $_REQUEST['account'] . ?    <input type="submit" class="button" value="Transfer Money" /> ';

In the last step are planned security controls and then, if is all ok, the transfer is done. Following is presented a snippet of the code of the last step (Note: in this example, for simplicity, there is no input sanitization, but it has no relevance to block this type of attack):

if( (!empty($_SESSION['antiCsrf'])) && (!empty($_POST['antiCsrf'])) ) {	//here we can suppose input sanitization code…

//check the anti-CSRF token if( ($_SESSION['antiCsrf'] == $_POST['antiCsrf']) ) {		echo ' '. $_POST['amount'] .' &euro; successfully transfered to account: '. $_POST['account'] .' '; }

} else {	echo ' Transfer KO '; }

As you can see the code is protected from CSRF attack both with a random token generated in the second step and accepting only variable passed via POST method. In this situation an attacker could forge a CSRF + Clickjacking attack to evade anti-CSRF protection and force a victim to do a money transfer without her consent. The target page for the attack is the second step of the money transfer procedure. Since the developers put the security controls only in the last step, thinking that this is secure enough, the attacker could pass the account and amount parameters via GET method. (Note: there is an advanced clickjacking attack that permits to force users to fill a form, so also in the case in which is required to fill a form, the attack is feasible). The attacker's page may look a simple and harmless web page like the one presented below:



But playing with the CSS opacity value we can see what is hidden under a seemingly innocuous web page.



The clickjacking code the create this page is presented below:

Trusted web page <style type="text/css"> www.owasp.com <form action="http://www.owasp.com"> <input type="submit" class="button" value="Click and go!">

<iframe id="clickjacking" src="http://localhost/csrf/transfer.php?account=ATTACKER&amount=10000" width="500" height="500" scrolling="no" frameborder="none">

With the help of CSS (note the #clickjacking block) we can mask and suitably position the iframe in such a way as to match the buttons. If the victim click on the button "Click and go!" the form is submitted and the transfer is completed.



The example presented uses only basic clickjacking technique, but with advanced technique is possible to force user filling form with values defined by the attacker.