Clickjacking - UI redress attack

Clickjacking - UI redress attack


The Internet is a scary place.

Web in a nutshell

No system is perfect, but the web is very far from perfect. There are many different ways to exploit web sites. As developers, it is our duty to make it as difficult as possible for bad guys to do bad things. Today we will touch upon clickjacking, also known as UI redress attack.

What is clickjacking?

OWASP says the following:

Clickjacking, also known as a “UI redress attack”, is when an attacker uses multiple transparent or opaque layers to trick a user into clicking on a button or link on another page when they were intending to click on the top level page. Thus, the attacker is “hijacking” clicks meant for their page and routing them to another page, most likely owned by another application, domain, or both.

Using a similar technique, keystrokes can also be hijacked. With a carefully crafted combination of stylesheets, iframes, and text boxes, a user can be led to believe they are typing in the password to their email or bank account, but are instead typing into an invisible frame controlled by the attacker.

For example, imagine an attacker who builds a web site that has a button on it that says “click here for a free iPod”. However, on top of that web page, the attacker has loaded an iframe with your mail account, and lined up exactly the “delete all messages” button directly on top of the “free iPod” button. The victim tries to click on the “free iPod” button but instead actually clicked on the invisible “delete all messages” button. In essence, the attacker has “hijacked” the user’s click, hence the name “Clickjacking”.

One of the most notorious examples of Clickjacking was an attack against the Adobe Flash plugin settings page. By loading this page into an invisible iframe, an attacker could trick a user into altering the security settings of Flash, giving permission for any Flash animation to utilize the computer’s microphone and camera.

Clickjacking also made the news in the form of a Twitter worm. This clickjacking attack convinced users to click on a button which caused them to re-tweet the location of the malicious page, and propagated massively.

There have also been clickjacking attacks abusing Facebook’s “Like” functionality. Attackers can trick logged-in Facebook users to arbitrarily like fan pages, links, groups, etc.

image property of


Clickjacking attacks are possible whenever websites can be framed. Therefore, preventative techniques are based upon restricting the framing capability for websites. Client side measures are possible (for example frame-busting scripts, or browser extensions like NoScript), but it's more efficient to take care of the problem server-side.

Portswigger (site by authors of WAHH, gold standard on web security) says following about frame busting:

Frame busting techniques are often browser and platform specific and because of the flexibility of HTML they can usually be circumvented by attackers. As frame busters are JavaScript then the browser's security settings may prevent their operation or indeed the browser might not even support JavaScript. An effective attacker workaround against frame busters is to use the HTML5 iframe sandbox attribute. When this is set with the allow-forms or allow-scripts values and the allow-top-navigation value is omitted then the frame buster script can be neutralized as the iframe cannot check whether or not it is the top window:

<iframe id="victim_website" src="" sandbox="allow-forms"></iframe>

Both the allow-forms and allow-scripts values permit the specified actions within the iframe but top-level navigation is disabled. This inhibits frame busting behaviors while allowing functionality within the targeted site.

Server side measures

Two mechanisms for server-side clickjacking protection are http security headers: X-Frame-Options and Content Security Policy (frame-ancestors directive, specifically).

Note: setting X-frame-options or frame-ancestors inside meta tag is useless! They need to be set on server.

What MDN says about X-Frame-Options:

There are two possible directives for X-Frame-Options:

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN

If you specify DENY, not only will attempts to load the page in a frame fail when loaded from other sites, attempts to do so will fail when loaded from the same site. 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.

There is also a third directive ALLOW-FROM uri, but it's obsolete and should not be used.

How to set X-Frame-Options header for some popular servers:

Configuring Apache
To configure Apache to send the X-Frame-Options header for all pages, add this to your site's configuration:

Header always set X-Frame-Options "SAMEORIGIN"

To configure Apache to set the X-Frame-Options DENY, add this to your site's configuration:

Header set X-Frame-Options "DENY"

Configuring nginx
To configure nginx to send the X-Frame-Options header, add this either to your http, server or location configuration:

add_header X-Frame-Options SAMEORIGIN always;

Configuring Express
To configure Express to send the X-Frame-Options header, you can use helmet which uses frameguard to set the header. Add this to your server configuration:
const helmet = require('helmet');
const app = express();
app.use(helmet.frameguard({ action: 'SAMEORIGIN' }));
Alternatively, you can use frameguard directly:
const frameguard = require('frameguard')
app.use(frameguard({ action: 'SAMEORIGIN' }))

If you host your app on S3 for example, then it gets a bit more tricky. You have to add headers using lambda@edge function.

See this tutorial for instructions:

Guide also mentions Mozilla observatory utility which can rate your site's security, ranging from F to A. Similar alternative site exists:

These sites include instructions how to improve your site's rating, like extending CSP with other directives.

Content Security Policy

Content Security Policy (CSP) is a detection and prevention mechanism that provides mitigation against attacks such as XSS and clickjacking. CSP is usually implemented in the web server as a return header of the form:

Content-Security-Policy: policy

where policy is a string of policy directives separated by semicolons. The CSP provides the client browser with information about permitted sources of web resources that the browser can apply to the detection and interception of malicious behaviors.

For now we will focus on single directive: frame-ancestors

The frame-ancestors 'self' directive is broadly equivalent to the X-Frame-Options sameorigin directive. The following CSP whitelists frames to the same domain only:

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

Alternatively, framing can be restricted to named sites:

Content-Security-Policy: frame-ancestors;

The following directive will only allow the page to be framed by other pages from the same origin:

frame-ancestors 'self'

The following directive will prevent framing altogether:

frame-ancestors 'none'

Using content security policy to prevent clickjacking is more flexible than using the X-Frame-Options header because you can specify multiple domains and use wildcards. For example:

frame-ancestors 'self' https://*

CSP also validates each frame in the parent frame hierarchy, whereas X-Frame-Options only validates the top-level frame.

Using CSP to protect against clickjacking attacks is recommended. You can also combine this with the X-Frame-Options header to provide protection on older browsers that don't support CSP, such as Internet Explorer.

The frame-ancestors directive obsoletes the X-Frame-Options header. If a resource has both policies, the frame-ancestors policy SHOULD be enforced and the X-Frame-Options policy SHOULD be ignored.


Security is hard, and bad guys will always be one step ahead.
However, by following advice from the security community, and keeping up to date with state of affairs in tech world, we should at least make it very difficult for bad guys to do damage.


Introduction - OWASP Cheat Sheet Series
Website with the collection of all the cheat sheets of the project.
Security and Identity | Web Fundamentals | Google Developers
Security is a big topic, learn about HTTPS, why it&#39;s important and how you can deploy it to your servers.
Web security
The web security-oriented articles listed here provide information that may help you secure your site and its code from attacks and data theft.
Web Application Security, Testing, & Scanning
PortSwigger offers tools for web application security, testing & scanning. Choose from a wide range of security tools & identify the very latest vulnerabilities.
Antonio Bradaric
View Comments
Previous Post

Fast and effective code reviews

Success! Your membership now is active.