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 includes the following PRACTITIONER-level labs:

5 Low-level logic flaw

This lab shows how attackers can exploit detailed flaws in application logic to bypass intended restrictions or gain unauthorized access.

6 Inconsistent handling of exceptional input

This lab demonstrates how inconsistent validation of unusual or unexpected input can be exploited by attackers.

7 Weak isolation on dual-use endpoint

This lab shows how endpoints that serve multiple purposes without proper isolation can be abused by attackers.

8 Insufficient workflow validation

This lab demonstrates how flaws in validating user workflows can be used to bypass business logic controls.

9 Authentication bypass via flawed state machine

This lab shows how attackers can exploit weaknesses in state management to bypass authentication mechanisms.

10 Infinite money logic flaw

This lab demonstrates how logical flaws in financial transaction systems can allow attackers to generate infinite funds.

11 Authentication bypass via encryption oracle

This lab shows how attackers can abuse encryption oracles to bypass authentication mechanisms.

LAB 5 - Low-level logic flaw

Lab Description :

image

Solution :

Add an item to the shopping cart; at this point, the maximum quantity is set to 99

image

🔄 Null Payloads for Repeated Requests

This enables you to generate payloads whose value is an empty string. You can use this to repeatedly issue the base request unmodified — you don’t need to configure payload positions.

You can use this payload type for a variety of attacks, for example:


🧪 Example Attack Scenario

Now, we will send the value 99 again and again so that the quantity value becomes negative due to flawed backend handling.

In Burp Suite Intruder:

This will cause the base request (with quantity = 99) to be sent repeatedly, exploiting logic flaws in the server’s price calculation or stock handling.

image

Refresh the shopping cart and observe that the price has become negative:

image

Next, adjust the quantity to precisely control the amount between 0 and 100 or how you like.

image


LAB 6 - Inconsistent handling of exceptional input

Lab Description :

image

Solution :

Finding Admin Panel

First, you need to locate the URI of the admin panel to delete the user “carlos.”

Go to Target -> Sitemap.

Right-click on the lab domain.

Select Engagement tools -> Discover content to find available pages and directories on the website.

image

When we try to browse to /admin, it says only persons belonging to DontWannaCry company can access this page.

image

Account Registration

Go to the registration page to create an account with the email ID given to us:

attacker@exploit-0ab1009903bcf40b8008753f01b300db.exploit-server.net

On the registration page, it is mentioned that we can use @dontwannacry.com if we are an employee of that company.

image

Create an account with very long email address ending with @exploit-0ab1009903bcf40b8008753f01b300db.exploit-server.net.

Example - very-long-string@YOUR-EMAIL-ID.web-security-academy.net

NOTE - The very-long-string should be at least 200 characters long.

So I created an account with a very long string - aafafasighfiyuqabryuawgfibasifnkajsdbgiuafgijaeboifnaijfaokjfiuahfjiahgr90ipqjro89sygfduygsfdtuvdtGUYEDFGWYTDVUYVDuyGDUYucvuavcuyvauyvdfuaycvuayvcuyasvcuyavcuyavcuucauvcuayvclu2o3i1hri97uuc89273r89hiug987niuch89qn397yr89hiu7ay89qah45uiyr0q@exploit-0ab1009903bcf40b8008753f01b300db.exploit-server.net

image

After completing the registration, a confirmation email is received.

image

Clicking the link in the email completes the registration successfully.

image

Login and Email Truncation

Now, log in as the user using the credentials we created:

` Username: test1 Password: 1234 `

Once logged in, we receive a welcome message. However, it’s important to note that the email address was truncated to 255 characters, as shown below:

aafafasighfiyuqabryuawgfibasifnkajsdbgiuafgijaeboifnaijfaokjfiuahfjiahgr90ipqjro89sygfduygsfdtuvdtGUYEDFGWYTDVUYVDuyGDUYucvuavcuyvauyvdfuaycvuayvcuyasvcuyavcuyavcuucauvcuayvclu2o3i1hri97uuc89273r89hiug987niuch89qn397yr89hiu7ay89qah45uiyr0q@exploit-0ab1009

This indicates that the backend is enforcing a maximum character limit (likely 255) for email addresses, possibly truncating values at the database or application level.

image

KEY INFORMATION TO NOTE


Register an Account with @dontwannacry.com

Taking note of the email truncation behavior, we can exploit this logic by registering an account with an email address that is:

The email id to be used now is

aaafasighfiyuqabryuawgfibasifnkajsdbgiuafgijaeboifnaijfaokjfiuahfjiahgr90ipqjro89sygfduygsfdtuvdtGUYEDFGWYTDVUYVDuyGDUYucvuavcuyvauyvdfuaycvuayvcuyasvcuyavcuyavcuucauvcuayvclu2o3i1hri97uuc89273r89hiug987niuch89qn397yr89hiu7ay89qah45uiyr0q@dontwannacry.com.exploit-0ab1009903bcf40b8008753f01b300db.exploit-server.net

Create an account with the above email-id

image

In the email inbox, click on the link to confirm registration.

image

Now finally when we log in, we can see that after truncation, our email address ends with @dontwannacry.com.

image

We can now access the admin panel at /admin.

image


LAB 7 - Weak isolation on dual-use endpoint

image

Solution :

The lab description says that user’s privilege level based on their input. So by somehow abusing this logic flaw we need to gain admin privileges.

Login as wiener using the credentials provided. image

As expected since weiner is a normal user, he is not allowed to access the /admin panel.

image

Logic flaw in password change functionality -

When we enter current password and old password to change the password of a user, the following POST request is sent to/my-account/change-password endpoint.

image

So as per this lab’s overview, we can try to remove a parameter/remove a parameter and value & see if anything wierd happens.

In the above request to change the password, we can see that the password change happens for the username that is being provided.

This is typically dangerous since in the password change functionality, if it is dependant on the username then an attacker can try to enter the username as admin & change the password.

Removing the &current-password= parameter -

When we remove the &current-password= parameter, notice that the server accepts the request and changes the password of wiener.

csrf=hDmgDzvRuQsMkrIMeamKQa2NiAjlViHD&username=wiener&new-password-1=1212&new-password-2=1212

image

Resetting admin’s password -

So this time we use this logic flaw to reset the password of administrator user.

In the form fill the username as administrator, and remove the &current-password= parameter.

The POST request now looks like this .

image

And we’ve finally changed/resetted the password of admin user.We can login as admin now using the password we just set.

image

Go to the admin panel & delete the user carlos to solve the lab.

image


LAB 8 - Insufficient workflow validation

Lab Description :

image

Solution :

So we need to abuse the flawed workflow while ordering a product to solve this lab.

Workflow

  1. First login as wiener .Click on the leather jacket product & add the item to cart.

image

The following request is sent.

POST /cart HTTP/1.1
Host:aef00b5046c7a4b83d0e156009e00ca. web-security-academy.net
Cookie: session=342CZuircwtnZmoAaSNwDSwpbsUL77uP
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
Origin: https://aef00b5046c7a4b83d0e156009e00ca. web-security-academy.net
Referer: https://aef00b5046c7a4b83d0e156009e00ca. web-security-academy.net/product?productId=1
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close

productId=1&redir=PRODUCT&quantity=1

In the cart page, we can see that the product is added & we can now place the order.

image

  1. When we place the order the following POST request is sent to /cart/checkout.
POST /cart/checkout HTTP/2
Host: aef00b5046c7a4b83d0e156009e00ca. web-security-academy.net
Cookie: session=FrFZmMsVa1rg3dwRExGgltBTD0gijy4m
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 37
Origin: https://aef00b5046c7a4b83d0e156009e00ca. web-security-academy.net
Referer: https://aef00b5046c7a4b83d0e156009e00ca. web-security-academy.net/cart
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers

csrf=viHBF1tw4OTvvpMH8ukIZ9TjfivZqcew

Case 1 - [ product_value > store_credit ]

But then we can’t buy the jacket($1337) since we have only $100.

image

Case 2 - [ product_value < store_credit ]

We repeat the same process again but this time we add a product that costs less than $100.

image

This time when we place the order, we have another request being sent after /cart/checkout which is a GET request to /cart/order-confirmation

image

Abusing flawed workflow logic -

Thinking from an attacker’s perspective, we can add any costly product, in our case the leather jacket & just resend the GET request to /cart/order-confirmation endpoint with parameter ?order-confirmation=true to place an order wihtout going through the intended workflow.

By this way we’re abusing the flawed workflow mechanism since the server doesn’t validate the workflow properly.

Now to solve the lab perform the following steps.

Refresh the page to confirm that the lab is solved.

image


LAB 9 - Authentication bypass via flawed state machine

Lab Description :

image

Solution :

We need to exploit the flawed workflow validation to login as administrator & delete the user carlos.

Using the content discovery tool in burpsuiter, we find that the admin directory is at /admin.

  1. Enter the given credentials for wiener and login.

image

  1. The following is the follow-up GET request made to /role-selector , which fetches the page to select the role which we want.
GET /role-selector HTTP/2

Now we’re presented with this page where we can select a role for the user.

image

  1. On selecting a role , the following request is sent.
POST /role-selector HTTP/2

role=user&csrf=wuxcQYkIOd5GkUbiEFaHIKkEAbIakcip

Abusing flawed workflow logic -

Thinking from an attacker’s perspective, we can try to just drop the GET request made to /role-selector and see what role we are assigned by default.

image

After dropping that particular request, we now see a link to Admin panel at the top right side.

image

This means that by default the application assigns administrator privileges to the user unless he specifies any role of his choice!.

Go to the admin panel and delete the user carlos to solve the lab.

image


LAB 10 - Infinite money logic flaw

Lab Description :

image

Solution :

Log in as wiener.

When we scroll down all the products in the home page, we can see that there is a signup feature.

image

When we signup, then site gives us a coupon code.

image

In the home page, we have a product called gift card. Add it to cart

image

Now in the cart section add the coupon SIGNUP30 to avail discount.

image

Once we place the order, we get a code to redeem.

image

Paste the coupon in the redeem section available at My-Account page to redeem some credits .

image

Now we got extra $3 dollars to our store credit.

image

Summary of the steps -

  1. Login as wiener .
  2. Signup for newsletter to get a discount coupon - SIGNUP30.
  3. Add Gift card product to cart .
  4. Apply SIGNUP30 coupon .
  5. Place the order to get a Gift coupon.
  6. Redeem the coupon in My-Account page to get $3 dollars.

On repeating this process again and again, we can gain more and more credits which will help us to buy the leet leather jacket. In order to automate this multi step process, we use macros feature in burp.

Automate the multi step process using macros -

Go to Project options > "Sessions.

image

In the Session handling rules panel, click Add. The Session handling rule editor dialog opens. In the dialog, go to the Scope tab. Under URL Scope, select Include all URLs.

image

Go back to the Details tab. Under Rule actions, click Add > Run a macro.

image

Under Select macro, click Add again to open the Macro Recorder.

image

Select the following sequence of requests:

POST /cart
POST /cart/coupon
POST /cart/checkout
GET /cart/order-confirmation?order-confirmed=true
POST /gift-card

image

image

Name the parameter gift-card and highlight the gift card code at the bottom of the response.

image

image

image

Now start the attack. It takes some time to run.

Once completed, we see that we have $1427 credits.

image

Now we can buy the leet jacket & solve the lab.

image


LAB 11 - Authentication bypass via encryption oracle

Lab Description :

image

Email Address Parsing Discrepancies

Complexity of Parsing Email Addresses

Email address parsing is inherently complex due to the diverse ways email addresses can be structured according to RFC standards.

Applications often need to extract domains from email addresses to determine the organization or to apply specific rules, which can lead to inconsistencies if not handled uniformly.

Exploitation Through Encoding

Attackers can use various encoding techniques to manipulate email addresses in a way that bypasses initial validation but causes discrepancies in parsing logic.

Common techniques include using different forms of encoding (e.g., URL encoding, Unicode) or leveraging rarely used syntax elements in email addresses.

Impact of Discrepancies

When discrepancies exist, attackers can exploit them to register accounts with email addresses that are technically valid but bypass intended restrictions.

This can lead to unauthorized access to parts of the application meant for specific users or roles, such as admin panels or restricted areas.

Example Exploits

An attacker might use an email address that appears to belong to a legitimate domain but includes encoded characters or subdomains that are not properly handled by the application.

This could allow the attacker to gain access to features or functionalities they should not be able to use.


Basic Structure

An email address is generally structured as:

local-part@domain

Example 1: "@"@example.com

Explanation:
Here, the local-part of the email address is "@", which is enclosed in quotes. According to RFC 5322, when the local-part is quoted, special characters such as @ are considered literal characters within the quotes. Thus, the email address is effectively:

@example.com

Example 2: "\"\"\""@example.com

Explanation:
In this example, the local-part is "\"\"\"". To include double quotes within a quoted local-part, each double quote must be escaped with a backslash. Therefore, the local-part is interpreted as a literal string containing escaped double quotes, and the email address is effectively:

@example.com

image

Comments

Example:

(comment)user@(comment)example.com

This is a valid email address.

image


Potential for Confusion

Solution :

In the login function, the web application is used stay logged into save user cookies.

image

A stay-logged-in is base64 cookie and added to the request. However, when decoding, it seems to have been encrypted first.

image

On the other hand, each post has a comment function. And when we leave an a123 invalid email like below:

image

The application then reports a line: Invalid email address: a123
and includes a notification Base64 cookie.

Decode it and observe that it is also encrypted.

We can infer (i.e., guess) that:

image

With a value “a” in this notification cookie cookie we generate an internal server error:

image

With a base64-encoded value “YQ==” we see information about the encryption. It looks it uses padded cipher and blocks of 16 bytes, so it could be AES-128:

image

We will verify by taking the value stay-logged-in of nofitication.

image

The results show that the content of stay-logged-in is username:timestamp.

image

Now, we need to create a value stay-logged-in for administrator or based on the encoding of the field notification. And since notificationit is created through the field email, we will pass the payload at email. We will pass it **administrator:** at email.

image

The message can be seen Invalid email address: administrator:1672593998338 with notification its base64 encoded form value of administrator:1672593998338. To do that, take the notification current value, decode the URL+base64 and remove the first 23 bytes.

Info:

image

image

image

After deleting the above 23 bytes, perform base64 encoding + URL encoding to pass into the cookie notification to see if it has been cut successfully: O3tEa1GHAnSumMNJYUyeNZmLguHpQlzLaC+N7hZEpoujFylp6tXe1Fc%3d. The result of the ciphertext message in notification must be a multiple of 16. I can guess the encryption algorithm for each block of 16 bytes.

image

So I need to insert any 9 bytes first to combine with the above 23 bytes into 32 bytes to delete.

image

Knowing it uses 16-bytes blocks and there is a prefix of 23 characters (“Invalid email address: “), we will add 9 characters of ”padding” in that second ciphered block:

image

We will take the encrypted value, URL-decode and base64-decode it, and delete the first 2 16-bytes blocks:

bRmw%2bImnDFvvwECQSiG1J8dfoUcrqKgkyQfr8wfI1J9bRCG%2bSLS06HPtXsMPhzuBQTkxD8oSxM2l3LhRCdZ3IQ%3d%3d
bRmw+ImnDFvvwECQSiG1J8dfoUcrqKgkyQfr8wfI1J9bRCG+SLS06HPtXsMPhzuBQTkxD8oSxM2l3LhRCdZ3IQ==
...
W0Qhvki0tOhz7V7DD4c7gUE5MQ/KEsTNpdy4UQnWdyE=
W0Qhvki0tOhz7V7DD4c7gUE5MQ/KEsTNpdy4UQnWdyE%3d

image

First we will set the value “W0Qhvki0tOhz7V7DD4c7gUE5MQ/KEsTNpdy4UQnWdyE%3d” for the “notification” cookie to check it is decrypted correctly:

image

We can delete the “session” cookie and use this value to log in:


GET /my-account?id=administrator HTTP/2
...
Cookie: stay-logged-in=W0Qhvki0tOhz7V7DD4c7gUE5MQ%2fKEsTNpdy4UQnWdyE%3d
…

image

And then delete the user and lab is solved:

image