Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/double-clickjacking-attack-flow.webp
Copy link
Collaborator

@kwwall kwwall Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, 2 things here that concern me:

  1. Why this image. I don't see anywhere in "cheatsheets/Clickjacking_Defense_Cheat_Sheet.md", that it's being referenced. (I've searched for the file name and 'img'.) It it is not referenced in this Clickjacking Cheat Sheet, why is it ever here?
  2. This image is straight out of Paulos Yibelo's blog (although there, it is a PNG file, rather than a WebP format; so apparently the format was converted.) If you did intend to use it, at a minimum, we at least need to acknowledge it as Yibelo's creation. And ideally, we ought to permission to use unless it unless it is clearly covered by some FOSS license that allows us to freely use it. While I don't believe you had malicious intentions, we certainly don't want to risk OWASP getting sued.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
169 changes: 167 additions & 2 deletions cheatsheets/Clickjacking_Defense_Cheat_Sheet.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Clickjacking Defense Cheat Sheet
# Clickjacking and Double Clickjacking Defense Cheat Sheet

## Introduction

This cheat sheet is intended to provide guidance for developers on how to defend against [Clickjacking](https://owasp.org/www-community/attacks/Clickjacking), also known as UI redress attacks.
This cheat sheet is intended to provide guidance for developers on how to defend against [Clickjacking](https://owasp.org/www-community/attacks/Clickjacking) (also known as UI redress attacks) and [Double Clickjacking](https://www.paulosyibelo.com/2024/12/doubleclickjacking-what.html?m=1) (also called forced multi-click exploitation)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Much better.


## Clickjacking

There are three main mechanisms that can be used to defend against these attacks:

Expand Down Expand Up @@ -311,3 +313,166 @@ Activate [designMode](https://developer.mozilla.org/en-US/docs/Web/API/Document/
```javascript
document.designMode = "on";
```

## Double Clickjacking

### Introduction

**Double Clickjacking** is an advanced variant of Clickjacking that exploits rapid user interactions by requiring two consecutive clicks to execute a malicious action. Unlike traditional Clickjacking, which typically relies on a single deceptive click, Double Clickjacking increases the attack success rate by bypassing single-click protections and evading common security measures.

## Attack Scenario

1. The attacker loads a malicious webpage containing a transparent iframe overlaying a legitimate website.

2. The user is tricked into clicking an element (e.g., a button or link), thinking it belongs to the attacker’s site.

3. The first click moves the transparent iframe into position over a critical UI element of the target website.

4. The second click executes a malicious action, such as transferring funds, changing security settings, or posting content without user consent.

## Ineffective Defenses

Traditional Clickjacking protections are ineffective against Double Clickjacking, as noted in research by Paulos Yibelo:

### 1. **X-Frame-Options:**

Attackers manipulate iframe positions dynamically, making this defense ineffective.

### 2. **Content Security Policy (CSP) Frame-Ancestors:**

This protection does not prevent UI manipulation via JavaScript or CSS.

### 3. **SameSite Cookies:**

Attackers do not need cross-site requests, rendering this defense ineffective.

## Advanced Mitigation Strategies

Given the shortcomings of traditional defenses, the following advanced approaches offer stronger protection against Double Clickjacking:

### **1. Detect Hidden Iframes Using Intersection Observer**

**Concept:** Attackers often use transparent or off-screen iframes. This detects and alerts users if such an iframe is capturing interactions.

```javascript
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (!entry.isIntersecting) {
alert("Warning: A hidden iframe may be attempting a Clickjacking attack!");
}
});
}, { threshold: 0.5 });

document.querySelectorAll("iframe").forEach(iframe => observer.observe(iframe));
```
Comment on lines +357 to +367
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmanico - I am not enough of a JavaScript expert to be able to discern if this is an effective defense against Double Clickjacking or not. Could you please take a look at this (lines 357-367) and give us your thoughts regarding it's effectiveness? It is very different than Yibelo's client-side JS defense. And I am a little concerned that this may have false positives (the assumption seemingly being it is rare for multiple entities to overlap) and also it may be a time-consuming defense if there are a lot of entities on a page, given that you'd need to check this on every page.


✅ Prevents hidden iframe overlays from capturing clicks.

✅ Ensures users interact only with visible elements.

#### **2. Enforce Click-Only on Trusted Domains**

**Concept:** Attackers host iframes on malicious domains. This script ensures actions only occur if the request comes from a trusted domain.

```javascript
if (document.referrer && !document.referrer.includes("your-website.com")) {
alert("Warning: Clicks from an untrusted source detected!");
}
```
Comment on lines +377 to +381
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. I'm not sure any website really should be trusted. Or at least there's a lot of cases not to do that. There are insider attackers. Also, this doesn't fit well into an "assume breach" mentality that many security conscious companies are now taking. (Also, we we're only concerned about cross-site requests SameSite cookies, CORS headers, etc. probably would be sufficient, shouldn't they?)
  2. I'm not confident this would work. I mean false positives would surely seem to be an issue, wouldn't it?

At a bare minimum, I will wait until @jmanico looks at this, but if it is valid, it probably needs a better explanation.


✅ Blocks interactions initiated from untrusted sites.

✅ Prevents attacks executed via external embedding.

### **3. Delayed Click Action (Click Delay)**

**Concept:** Prevents rapid unintended double-clicks by enforcing a minimum delay between clicks.

```javascript
let lastClickTime = 0;
document.getElementById("submitButton").addEventListener("click", function (event) {
const now = Date.now();
if (now - lastClickTime < 500) { // 500ms delay
event.preventDefault();
alert("Double-click detected! Please click only once.");
} else {
lastClickTime = now;
// Proceed with the action
}
});
```
Comment on lines +391 to +403
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems feasible. Have you tried this on Yibelo's PoC on his blog post?
What do you think @jmanico ?


✅ Makes it harder for attackers to exploit timing tricks.

✅ Prevents unintended double-clicks on sensitive actions.

#### **4. Trusted Interaction Verification**

**Concept:** Adds an explicit user confirmation step before executing sensitive actions.

```javascript
function confirmAction() {
let confirmation = confirm("Are you sure you want to proceed?");
if (confirmation) {
// Perform action
}
}
```
Comment on lines +413 to +420
Copy link
Collaborator

@kwwall kwwall Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um, TBH, I'm beginning to wonder if you are missing the point about how Clickjacking iis exploited in general. The targeted system is just there to entice the user to click or to garner the user's trust. The way this "UI redress" works is the attack places something dangerous (e.g., a site that might download malware) in a transparent overlay over something that the user generally thinks would be safe to click on (the underlying iframe of the targeted system). That overlaid system may or may not overlay "sensitive data". And you surely cannot do this on every page. You couldn't even use it on something like a financial or health insurance site, because there pretty much everything is sensitive on almost every page. Thus using something the above on such a site would be very intrusive. If it did work (and do you really think the average user is going to do a 'view source' or open the browser's web development tools and try to figure it out?), the defense needs to be unobtrusive and not require any special intelligence from the end user.


✅ Requires user intent verification before execution.

✅ Reduces accidental malicious actions.

### **5. Prevent Rapid UI Manipulation Using Mutation Observers**

**Concept:** Monitors for sudden UI changes (such as iframe repositioning) and blocks suspicious activity.

```javascript
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === "childList" || mutation.type === "attributes") {
alert("Suspicious UI changes detected!");
}
});
});
observer.observe(document.body, { childList: true, subtree: true, attributes: true });
```

✅ Detects hidden UI manipulations in real time.

✅ Prevents attackers from dynamically repositioning elements for Clickjacking attacks.

### **6. Require Intent-Based Gestures for Critical Actions**

**Concept:** Instead of a simple click, users must perform a deliberate gesture, like dragging a slider, before confirming actions.

```html
<label for="secureAction">Slide to confirm:</label>
<input type="range" id="secureAction" min="0" max="100" oninput="checkGesture(this.value)">
<script>
function checkGesture(value) {
if (value == 100) {
alert("Confirmed! Action executed.");
}
}
</script>
```
Comment on lines +447 to +459
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seriously, a slider on every page? Really? Because prior to X-FRAME-OPTIONS and CSP frame-ancestors, we had to put the anti-frame busting JavaScript on every bloody page, so I don't see why this would any different. You can't do something that is going to require an explicit action every time a page loads.


**How the Slider Works:**
A slider is an effective method for ensuring deliberate user intent before executing a critical action. Instead of a simple button click—which can be accidental or manipulated—users must perform an intentional gesture, such as sliding to a specific position, to confirm their choice.

✅ Users must actively confirm before execution.

✅ Prevents forced clicks leading to unintended actions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, what is so wrong about dropping Yibelo's suggested client-side defense here?

    (function(){
    if (window.matchMedia && window.matchMedia("(hover: hover)").matches) {
        var buttons = document.querySelectorAll('form button, form input[type="submit"]');
        buttons.forEach(button => button.disabled = true);
        
        function enableButtons() {
            buttons.forEach(button => button.disabled = false);
        }
        
        document.addEventListener("mousemove", enableButtons);
        document.addEventListener("keydown", e => {
            if(e.key === "Tab") enableButtons();
        });
    }
})();

Presumably that at least is effective against his PoC. He'd lose a lot of credibility if it wasn't? At a bear minimum, I think we should include it.

Also, is there any reason why the standard anti-frame busting script that most companies use (and it probably still mentioned for standard clickjacking in this Cheat Sheet, although no longer as a preferred mechanism), not effective against double-clickjacking as well? Based on the small part that I understand about it, I think that it would.

## Conclusion

**Double Clickjacking** is a sophisticated attack that evades traditional Clickjacking defenses. Implementing a combination of Intersection Observer detection, Click Delay, Pointer Events, Trusted Domain Enforcement, Trusted Interaction Verification, Mutation Observers, and Gesture-Based Confirmations provides robust protection against this emerging threat. A layered security approach is essential to safeguarding users from evolving Clickjacking techniques.

### For a more in-depth understanding of double-click jacking and its implications, you can refer to the following articles-

- [New "DoubleClickjacking" Exploit Bypasses Clickjacking Protections](https://thehackernews.com/2025/01/new-doubleclickjacking-exploit-bypasses.html)

- [Don’t Click Twice—New Chrome, Edge, Safari Hack Attack Warning](https://www.forbes.com/sites/daveywinder/2025/01/05/dont-click-twice-new-chrome-edge-safari-hack-attack-warning/)

- [Emerging ‘DoubleClickjacking’ Threat Exploits Double-Clicks for Account Hijacking](https://www.bitdefender.com/en-us/blog/hotforsecurity/emerging-doubleclickjacking-threat-exploits-double-clicks-for-account-hijacking)