Skip to main content

Clickjacking attacks: definition and mitigation mechanisms

What is a clickjacking attack and how is it launched?

Clickjacking attacks are also known as user interface (UI) redress attacks and belong to the category of user interface misrepresentation of critical information [0]. In order to launch a clickjacking attack the attacker creates a malicious website by combining multiple layers (transparent and opaque) so as to deceive users who think are clicking a link inside the website they are viewing when in fact they are clicking an invisible superior element [1]. This same technique can be used to “hijack” the pressed keys when the user types in a text field of the malicious website.

For the purpose of preparing a website with these characteristics, the attacker needs the following:
  1. Be able to embed inside the malicious website the content of another website or web application (the victim of the attack) whose users are to be deceived. This can be achieved by using HTML frame or iframe tags. For example, the website of a bank could be embedded.
  2. Adjust the design of the malicious website using CSS style sheets so that the inserted content at the previous step is invisible for the user. Then, the attacker adds a new visible layer but located behind the inserted content. In this new layer elements are defined and lined up exactly behind the elements of the inserted and invisible content. For instance, if the website of the bank has a section to make money transfers with a button "Transfer funds", the attacker may add a visible layer (but located behind) with a button perfectly aligned with the original from the bank but with an attractive message such as “Get a free iPad”. By doing this, the malicious website would be showing a button the user could click but in reality they would be clicking on the invisible superior button which confirms the funds transfer without the user noticing it.

The following two figures (credits Open Web Application Security Project) represent the overlap between the invisible superior layer of the embedded website and the visible inferior layer which the user finally visualizes and attempts to interact with [2].

Figure 1: Description of the attack

Figure 2: Original website embedded and invisible

It is important to be clear on two points over the above mentioned:
  1. A bank website was used as an example, but in practice an attacker may try to embed any other existing website.
  2. The are several mechanisms to prevent this type of attack on a website. For this, some configuration and/or programming adjustments have to be done to prevent the website from being embedded from another external website.

How can I know if my website is potentially vulnerable to a clickjacking attack?

The simplest way is to create a HTML code like the following but the URL of the website we want to analyzed is replaced inside the iframe tag. In this case, the value that would need to be replaced by another is
    <title>Verify clickjacking vulnerability</title>
    <p>Test result:</p>
    <iframe src="" width="500" height="500">
Once the file with the above HTML code has been created, the next step is simply to open it from a browser. If when doing it the embedded website can be visualized (as shown in figure 3) it means it is vulnerable to a clickjacking attack. Whereas if the the site is not visualized (as shown in figure 4) this is because some sort of protection mechanism has been implemented against this type of attack, although this does not guarantee the site is totally immune.

Figure 3: Vulnerable website
Figure 4: Not vulnerable website

Another way of verifying this is to use a web tool. For example, has a very complete and intuitive web application [19]. Or this web application basically performs the same test as the previous HTML code [3].

How can this vulnerability be mitigated?

Basically there are three forms of defense against a clickjacking attack which are independent from each other but can be combined for better results: [4]:
  1. Use the HTTP headers X-Frame-Options [5] and/or Content Security Policy (CSP) [6][7]: This is a server-side protection technique. Both HTTP headers serve to specify if the website can be embedded into another one. However, they have some differences such as the following:

  2. X-Frame-Options: This header serves to indicate the browser if embedding the website is allowed through the HTML frame, iframe, object o embed tags [8]. The possible values for this header are:
    • X-Frame-Options: "DENY"
    • X-Frame-Options: "SAMEORIGIN"
    • X-Frame-Options: "ALLOW-FROM"
    In the first case, the value DENY means the website cannot be embedded. In the second case, the value SAMEORIGIN specifies that it can only be embedded within the same website. And in the third case the value ALLOW-FROM defines it can only be embedded within the specific external website (using only the HTTPS protocol and the default port 443).

    The limitations of using this header are the following [4]:
    • It is necessary to include the header in the HTML code of all the website pages which need protection.
    • It does not allow a definition of a white list of domains or external sites which could embed the website.
    • The value ALLOW-FROM was added in the year 2012 and it is still not fully supported by some browsers.
    • It does not accept multiple values (for example, SAMEORIGIN and ALLOW-FROM cannot be used at the same time).
    • Even though at present it is partially supported by most browsers, the use of this header is deprecated in favor of the frame-ancestors directive of the Content Security Policy (CSP) HTTP header.

    The compatibility of this HTTP header with different browsers can be verified in these links: [9][10].

    Content Security Policy (CSP): This header allows to specify the value of the frame-ancestors directive in order to indicate the browser if it is permitted or not to embed the website through the HTML frame, iframe, object, embed o applet tags [11][12]. Some examples of the use of this directive are detailed as follows:
    • Content-Security-Policy: frame-ancestors 'none';
    • Content-Security-Policy: frame-ancestors 'self';
    • Content-Security-Policy: frame-ancestors 'self' *;
    In the first case, the value none is assigned to the frame-ancestors directive, which means the website cannot be embedded. In the second case, the value self specifies that it can only be embedded within the same website. And in the third case the value assigned means it can be embedded within the same site, within any other site from the domain (using any protocol) and within the site (using only the HTTPS protocol and the default port 443).

    The limitations of using this header are the following [4]:
    • It is still not fully supported by the main browsers.
    • The header X-Frame-Options takes priority.

    The compatibility of the frame-ancestors directive with the main browsers can be consulted in these links: [13][14].

  3. Establish the SameSite attribute in the session cookies with the value strict or lax [15][18]. When doing this, the session cookies are not included by the browser in the requests generated from another website through an indirect call, which is what happens when using a HTML iframe tag. This is technique mainly used as defense against cross-site request forgery (CSRF) attacks but it can also be used for clickjacking attacks

  4. The limitations of using this defense mechanism are the following [4]:
    • If the website does not require user authentication this mechanism brings no protection.
    • Even if the attribute is supported by all modern browsers, there are still many users who continue using outdated browsers without this support.

    The compatibility of the SameSite attribute with the different browsers can be verified in the following link: [16].

  5. Using a framebusting or framebreaking code: It is a client-side protection technique. It consists in including a javascript code inside the website to prohibit its content from being embedded in another site. This technique is not very effective and can be bypassed in many ways, which is why it should only be used as basic protection if the idea is to maintain compatibility with legacy browsers [17].


At present, there isn’t a single mechanism that can be used as defense against all potential clickjacking attacks. That is why the best defense technique is a combination of the different options here analyzed. It would be ideal to combine the use of the HTTP headers X-Frame-Options and Content Security Policy (CSP). Aditionally, if the website requires users to authenticate, it is advisable to define the SameSite attribute in the session cookies as seen previously. Finally, if the website needs to maintain compatibility with legacy browsers (which do not support the HTTP headers mentioned or the SameSite attribute in the cookie sessions) adding a framebusting or framebreaking technique is recommended.
In our next blog post we are going to develop a practical example of how to implement the use of the HTTP headers X-Frame-Options and Content Security Policy (CSP) to mitigate the possibility of a clickjacking attack in a specific website or web application.

See you soon!