Cyberlium

Web › Module 2 › Lesson 3

BeginnerModule 2Lesson 3/5

Clickjacking and Frame Abuse

A02: frame DENY on — X-Frame-Options / CSP.

15 min+40 XP3 quiz
Module progress3 of 5

Visual · clickjacking_frame

Clickjacking defense: 0.0.1:8769. X-Frame-Options / CSP frame-ancestors.

Opening

Clickjacking is not “iframe exists.” It is your UI acting under someone else’s page without the user meaning to.

An attacker hosts a page that iframes your site (or a sensitive flow) under a deceptive overlay. The victim thinks they click the attacker’s button; they actually confirm a transfer, follow, or settings change on your origin. That is UI redressing — classic when framing is allowed. OWASP Top 10:2025 A02 covers missing frame defenses as misconfiguration. This is ORIGINAL Cyberlium teaching.

1. Mechanism: framed sensitive UI + deceptive overlay = unintended action

Browsers allow embedding unless headers or CSP say otherwise. If your change-password or confirm-pay page can be framed, a malicious parent can align invisible controls under fake buttons. Same-site cookies may still send. The victim’s intent is hijacked; the request looks legitimate to your server. Finding language: “Sensitive flows frameable; missing X-Frame-Options / frame-ancestors.” Fix language: “DENY or SAMEORIGIN; CSP frame-ancestors 'none' or allowlist; confirm critical actions with re-auth when needed.”

Command guide

A02 Misconfig — Mechanism

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8769"

Command — copy this

curl -sS -m 3 -I "$SAFE/" | grep -i -E "x-frame-options|content-security-policy|frame-ancestors"

2. Defenses: X-Frame-Options and CSP frame-ancestors

X-Frame-Options: DENY blocks all framing; SAMEORIGIN allows same-origin frames. CSP frame-ancestors is the modern directive and can allowlist specific parents. Prefer setting both during transition if your stack needs it — test YOUR app. frame-ancestors 'none' is the strict literacy default for sensitive pages. JavaScript frame-busting alone is historically brittle; headers/CSP are the shipping control. Do not teach “bypass framebust” cookbooks here.

Command guide

A02 Misconfig — Defenses

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8769"

Command — copy this

curl -sS -m 3 -I "$SAFE/broken" | grep -i -E "x-frame-options|frame-ancestors"
curl -sS -m 3 -I "$SAFE/hard" | grep -i -E "x-frame-options|frame-ancestors"

3. What is out: UI-redress kits and foreign targets

Building a transparent overlay against a live bank, school portal, or classmate app is unauthorized social/technical abuse. Cyberlium demos: identify DEMO, then serve a toy page on 127.0.0.1:8769 with DENY, curl -I the child path, record the header. That is enough. No BeEF. No hydra of 192.168.0.1. No “victim lure” pages aimed at humans outside written people-scope (this course has none).

Command guide

A02 Misconfig — What is out

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8769"

Command — copy this

curl -sS -m 3 -I "$SAFE/" | head -n 16

4. Tie-back to headers lesson and A02 checklist

Clickjacking defense is one line on the A02 hardening checklist next to CSP and nosniff. Missing it is misconfiguration even when the rest of the app is careful. Record whether YOUR sensitive routes send frame defenses.

5. What you record

Date (UTC). Clickjacking = framed UI + deception. Defenses: X-Frame-Options / frame-ancestors. curl -I observation on DEMO or SAFE 127.0.0.1:8769. Ethics: NEVER foreign UI-redress; NEVER BeEF; NEVER hydra/nmap the LAN. Path: $HOME/cyberlium-lab/a02-clickjack-notes.txt, chmod 600. Legal: original Cyberlium — not official OWASP certification.

6. Wrong vs right: redress kits vs frame deny on YOUR pages

Worked failure — same iframe tag, opposite target. Right never needs a victim lure.

  • Wrong

    Overlay a bank or classmate app. Hydra the home router. Ship clickjack PoC kits. Skip headers and “test on production users.”

  • Right

    Identify DEMO; serve toy pages on 127.0.0.1:8769 with DENY; curl -I; lock a02-clickjack-notes.txt. Next: Lab — Harden Config on Loopback.

Create parent and child pages locally. Child sets DENY. curl -I proves the header. chmod 600.

Command guide

a02_clickjack_demo.sh — DEMO identify + frame DENY on 127.0.0.1:8769

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl
sudo apt install nmap
sudo apt install python3

macOS:

Command — copy this

brew install nmap
brew install python3

Windows: Built-in (PowerShell: Invoke-WebRequest)

Command — copy this

choco install nmap  # or download https://nmap.org/download.html

Download https://python.org/downloads/

═══ COMMANDS ═══

Command — copy this

cd "$HOME/cyberlium-lab"

Command — copy this

SAFE="http://127.0.0.1:8769"

Command — copy this

cat > a02_clickjack_demo.py << 'PY'
from http.server import BaseHTTPRequestHandler, HTTPServer

HOST = "127.0.0.1"  # bind only — never 0.0.0.0, never argv
PORT = 8769
if HOST != "127.0.0.1":
raise SystemExit("refusing non-loopback bind")

CHILD = b"<html><body><h1>sensitive toy action</h1><button>Confirm</button></body></html>"
PARENT = b"""<html><body><h1>local parent</h1>
<iframe src="http://127.0.0.1:8769/child" width="400" height="200"></iframe>
</body></html>"""

class H(BaseHTTPRequestHandler):
def do_GET(self):
    if self.path.startswith("/child"):
        body = CHILD
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
        self.send_header("X-Frame-Options", "DENY")
        self.send_header("Content-Security-Policy", "frame-ancestors 'none'")
    else:
        body = PARENT
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
    self.send_header("Content-Length", str(len(body)))
    self.end_headers()
    self.wfile.write(body)

print("bind", HOST, PORT)
print("demo_writeup_url http://192.168.0.1/")
print("if 192.168.0.1 is a router, curl -I", f"http://{HOST}:{PORT}/child")
print("ethics: NEVER foreign clickjack kits; NEVER BeEF; NEVER hydra/nmap the LAN")
print("legal: original Cyberlium — not official OWASP certification")
HTTPServer((HOST, PORT), H).serve_forever()
PY

Command — copy this

cat > a02_clickjack_practical.sh << 'SH'
SAFE="http://127.0.0.1:8769"

curl -sS -I "$SAFE/child" | grep -i -E 'HTTP/|X-Frame-Options|Content-Security-Policy'

SH

Command — copy this

{

Mission: a02-clickjack-notes.txt in cyberlium-lab (mode 600)

1) 0.0.1:8769.2) curl -I SAFE /child; record DENY / frame-ancestors; fill notes chmod 600. 3) Ethics: no foreign kits, no hydra/nmap of the LAN.

Stuck? Ask Cyberlium AI Mentor

If “I need a real victim page to learn clickjacking” still feels true, ask for a hint — not a lure kit. Try: "Hint only: how framing enables UI redress, which curl -I lines prove DENY on 127.0.0.1:8769, and where locked a02-clickjack-notes.txt lives?"

You now treat clickjacking as frame abuse stopped by X-Frame-Options / CSP frame-ancestors — an A02 posture control — with curl on YOUR lab or SAFE loopback and locked notes. Original Cyberlium — not official OWASP certification. Next — Lab — Harden Config on Loopback.

Knowledge Check

1

APPLY: A sensitive confirm page can be iframed by any origin. What failed, and what do you ship?

Multiple choice

Knowledge Check

2

APPLY: True or False: JavaScript frame-busting alone is the preferred modern defense versus CSP frame-ancestors.

True or False

Knowledge Check

3

APPLY: curl http://192.168.0.1/ shows Huawei Router Admin. What do you do?

Multiple choice

← Previous

Answer all 3 knowledge checks to continue. (0/3 answered)