Welcome back to another installment of “Attacks You Should Know About”! If you’ve been following along, you already know that web applications are full of potential vulnerabilities. Today, we’re diving into one of the more interesting client-side vulnerabilities: clickjacking. It’s subtle, sneaky, and surprisingly common. Let’s break down how it works, why it’s dangerous, and what can be done to prevent it.

What is Clickjacking?

Clickjacking is a UI redress attack that tricks a user into clicking something different from what they perceive, effectively hijacking their clicks. It often involves embedding a legitimate website or button inside a transparent or opaque frame (usually an iframe) over a decoy UI. From the user’s perspective, they’re interacting with a harmless element—like a “Play” button or a form field—but in reality, they’re performing consequential actions on another website without their knowledge.

While it might sound abstract, clickjacking can lead to real-world consequences. For example, an attacker might trick a user into liking a social media post, changing account settings, or even transferring money—just by framing the right UI elements in the right way. Speaking of framing, lets take a look a critical component to this attack, iframes.

Inline Frames

Inline frames, commonly abbreviated as iframes, are HTML elements that allow web pages to embed another HTML page within itself. The embedded web page retains its own context (scripts, css styles, cookies, etc.) and can come from the same origin, or a different one. Let’s take a look at a simple example:

Utilizing this iframe would display the contents from `example.com` on our page within a 600 pixel wide and 400 pixel tall box. This is done to do things like embedding a YouTube video on a website for the user to interact with.

How Clickjacking Works

Since the core of clickjacking is done through visual deception, the main components to constructing an attack is through CSS and iframes. Let’s break it down:

  1. A threat actor begins by picking or creating a web page. It can be built to do anything, but most likely will contain forms where users will input their information, and/or buttons to interact with.
  2. The site the victim **thinks** they will be interacting with is loaded inside of an invisible iframe, positioned over the clickable elements of the malicious page.
  3. The user receives a link to the page (often through a believable phishing attack) and begins interacting with it, unknowingly performing sensitive actions they are unaware of.

Let’s take a look at one of Portswigger’s Web Security Academy labs to get a better understanding of this in practice. If you want to follow along, you can check out Portswigger’s clickjacking topic here.

Basic Clickjacking

Upon logging into the application, we can see that there’s two buttons: “Update email” and “Delete account”. Our goal is to trick the user into clicking the button to delete their account.

Let’s begin crafting our clickjacking attack. I like using the following template to check for clickjacking:

If the page is vulnerable, we would expect to see a small box with the contents of the account page in our browser. Let’s input our URL and open the document:

Awesome, we can successfully perform clickjacking on this web page! Let’s take things a step further and make our payload more complicated.

We’re going to adjust the sizing and opacity of the webpage, as well as adding a message prompting the user to click it. Let’s look our new payload and the outcome:

As we can see, the embedded page is much larger than the previously small box we were working with and set the opacity to be barely visible. Let’s keep messing with our div and iframe opacity to make this more practical.

Now we have the text overlapping the sensitive function. I used red outline to show about the size of the embedded target, But from the victim’s point of view, they only see a blank web page with text prompting them to click there. While this functionally would accomplish what we want, it is very unlikely a user would click on such a mysterious page. Let’s take it up one more notch.

Look familiar? With a little help from ChatGPT, I was easily able to create a much more convincing web page. I didn’t include the HTML this time around since all of it doesn’t fit on one page. Now the likelihood of a user wanting to click the button has exponentially increased. Little do they know, they would be deleting their account.

Clickjacking Mitigations

So how do we mitigated clickjacking? The first preventive measure should is setting proper server-side headers that restrict how your application can be embedded in other sites. A common starting point is using the X-Frame-Options header, which lets you block all framing (DENY) or limit it to the same origin (SAMEORIGIN). However, the modern and more flexible approach is to use the Content-Security-Policy header with the frame-ancestors directive. This gives you more control over which domains can frame your content, and is supported by most modern browsers. It’s also important to avoid relying solely on client-side frame busting scripts, which are often bypassed or blocked. For defense-in-depth, consider applying both headers, especially if your user base spans a variety of browsers and devices. For a more in-depth guide on how to prevent clickjacking, I highly recomened checking out OWASP’s cheat sheet on preventing clickjacking.

Warning: Please do not try these tactics and techniques on any domain without explicit permission from the domain owner. This information is provided solely for educational purposes, and Abricto Security is not responsible for any individuals who use these tactics and techniques in an unauthorized or malicious manner.