DEV Community

Cover image for Prevent Click-Jacking in your web applications
Maulik Thaker
Maulik Thaker

Posted on

Prevent Click-Jacking in your web applications

Today we gonna lookout the click jacking also known as UI redressing and how we can prevent that in our web applications or website.

What is Click-jacking?

Clickjacking is an attack that tricks a user into clicking a webpage element which is invisible or disguised as another element. This can cause users to unwittingly download malware, visit malicious web pages, provide credentials or sensitive information, transfer money, or purchase products online.

For example, if you have your application which contains login and sign-up kind of forms then it might be a chance to getting under attack of click jacking where a fake UI layer is attached through an <iframe src=""> tag and embedded into the top of your site.

Consider the example below:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Click jacking</title>
  <style>
    .toplayer{
       position: relative;
       width:100%;
       z-index:1; 
     } 
     #topmostlayer{
       position: absolute;
       z-index: 9999;
       opacity: 0.0001;
       top: 50%; 
       left: 50% // can be adjusted according to your login button UI placements
     }
  </style>

</head>
<body>
  <form >
    <input type="text" placeholder="Enter username"> 
    <input type="password" placeholder="Enter password">
  <button class="toplayer btn btn-login">Login</button>
  </form>
  <a id="topmostlayer" role="button"> Click here 
   <iframe  src="https://anonymous-web.com"></iframe>
  </a>

</body>
</html>
Enter fullscreen mode Exit fullscreen mode

In above code, we can see that the login form is there at topmost UI level so whenever URL loads the login page, in DOM tree UI of login is placed at top layer.

Now, What is interesting here is you can do DOM manipulation using our well-known css property of z-index along with <iframe> tag embedded inside <a> tag.

Here css class named .toplayer is added to Login button and the z-index of this class can be set to 1 or bydefault. So, whenever <iframe src="https://anonymous-web.com"> is came into DOM along with id of <a> tag named #topmostlayer attackers identify your button position in DOM and create exact same replica or placed the position of buttton named "click here" as such that button is overlapped into login button.

  #topmostlayer{
       position: absolute;
       z-index: 9999;
       opacity: 0.0001;
       top: 50%; 
       left: 50% // can be adjusted according to your login button UI placements
     }
Enter fullscreen mode Exit fullscreen mode

Observe that button "Click here" id styles. You can see that z-index: 9999; forces the UI to be on top layer on login button also css propery opacity:0.0001; hides that UI so that you are not aware of any UI is present in your existing DOM level. Such attacks called as UI redressing.

Alt Text

Check Click-jacking vulnerability

There are many online tools by which you can check whether our deployed URL can be embedded into another URL or not. Examples are Clickjacker, Lookout, gf-dev. I preferred "Clickjacker" because there you can test your deployed URL and it gives you a POC and identify the X-frame-options, CSP headers, Raw Http headers information about your URL. If X-frame-option is "sameorigin" then it indicates your URL is safe.

Alt Text

below is screenshot of Raw Http headers in case of there is chances of attacks.

Alt Text

How to prevent Click-jacking?

1. Frame Busting

Simple task is to avoid UI overlapping or DOM manipulation by <iframe> tag. At frontend side, when page loads at that time we can check whether any UI layer inserted into top of the HTML of <body> tag or not by adding below code.

<style>
/* Hide page by default */
html { display : none; }
</style>
<script>
if (self == top) {
// Everything checks out, show the page.
document.documentElement.style.display = 'block';
} else {
// Break out of the frame.
top.location = self.location;
}
</script> 
Enter fullscreen mode Exit fullscreen mode

Above technique called Frame busting. JavaScript that runs on user’s browser is used to stop itself being embeded into iframe and escape out of it. When the page loads, this JS code will check if the domain of the page matches the domain of the browser window. If it does then no problem, if it does not then it will escape out of the iframe and load the site in the browser by replacing the site trying to load it in the Iframe.

2. X-Frame Options & Content-Security-Policy

At server side we can set X-Frame-Options is a response header. Developers can use it to protect their site against clickjacking. It can be used to indicate whether or not a browser should be allowed to render a page in an Iframe by have its value set as any of the following:

X-FRAME-OPTIONS: DENY

By specifying DENY, no site will be allowed to load the page in a frame.

X-FRAME-OPTIONS: SAMEORIGIN

On the other hand, if you specify SAMEORIGIN, you can still use the page in a frame as long as the site including it in a frame is the same as the one serving the page.

X-FRAME-OPTIONS: ALLOW-FROM uri

If you specify this, then the site can be displayed in a frame only by uri specified. However, this is an obsolete directive that no longer works in modern browsers.

The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page. It is used for a vast number of security vulnerabilities other than clickjacking such as XSS. However our guide will be focussed on its use in protection against clickjacking only. The HTTP Content-Security-Policy (CSP) frame-ancestors directive specifies valid parents that may embed a page using an Iframe. It can be used to indicate whether or not a browser should be allowed to render a page in an Iframe by have its value set as any of the following:

Content-Security-Policy:frame-ancestors 'none'

By specifying ‘none’, no site will be allowed to load the page in a frame.

Content-Security-Policy:frame-ancestors 'self'

On the other hand, if you specify ‘self’, you can still use the page in a frame as long as the site including it in a frame is the same as the one serving the page.

Content-Security-Policy: frame-ancestors uri

If you specify this, then the site can be displayed in a frame only by uri specified. For example: If you implement the below header directive, then your site will be allowed to be iframed only by the specified url.

Top comments (1)

Collapse
 
seeker profile image
seeker

Where in my react app., I can set X-FRAME-OPTIONS: DENY ? Iam using craco config to override react scripts webpack config. There I have configured X-FRAME-OPTIONS: DENY., but still it is clickjack vulnerable:

module.exports = {
devServer: {
compress: true,
headers: {
'X-Frame-Options': 'SAMEORIGIN',
},
},
}