> For the complete documentation index, see [llms.txt](https://ganesha-hk.gitbook.io/cybersecurity-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-jwt-labs/lab-8.md).

# lab-8

## JWT Authentication Bypass via Algorithm Confusion with No Exposed Key

**Difficulty:** Expert

### Lab Description

This lab uses a JWT-based mechanism for handling sessions. It uses a robust RSA key pair to sign and verify tokens. However, due to implementation flaws, this mechanism is vulnerable to algorithm confusion attacks. Unlike the previous lab, the public key is not directly exposed.

**Objective:** Derive the server's public key, use it to sign a modified session token that gives you access to the admin panel at `/admin`, then delete the user `carlos`.

**Credentials:** `wiener:peter`

### Root Cause

The application was vulnerable to an **algorithm confusion attack** due to improper use of a generic JWT verification function. The JWT library provided a single method such as `verify(token, key)` that determines the verification algorithm from the user-controlled `alg` header instead of using a fixed, server-configured algorithm.

The application was designed to use **RS256**, where the server signs JWTs with its RSA private key and verifies them with the corresponding public key. During verification, the developer always passed the server's public key to the generic verification function:

```
publicKey = serverPublicKey
verify(token, publicKey)
```

An attacker changed `alg` from `RS256` to `HS256` and generated a **new HS256 signature** using the derived RSA public key as the HMAC secret. Since both the attacker and the server used the **same public key bytes** as the HMAC secret, the signature matched and the server accepted the forged JWT.

The key difference from lab 7 is that the public key is **not directly exposed** via `/jwks.json` — it must be derived mathematically from two observed JWT signatures using a known cryptographic technique.

### Exploitation

1. Start the login flow and capture the first JWT.
2. Log out and log in again to capture a **second distinct JWT** signed by the same RSA private key.
3. Use the `sig2n` tool to derive the RSA public key from the two diffrent JWT token:

   ```
   docker run --rm -it portswigger/sig2n <token1> <token2>
   ```

   This outputs one or more candidate Base64-encoded public keys.
4. In Burp's **JWT Editor Keys** tab, click **New Symmetric Key → Generate**.
5. Replace the `k` parameter value with one of the Base64-encoded candidate keys from step 3. Save the key.
6. In Repeater, update `"sub"` to `"administrator"` and change the URL to `GET /admin`.
7. Sign the JWT using the new saved HS256 key.
8. Send the request and open the response in the browser.
9. Click **Delete carlos** in the browser and capture the resulting request.
10. Find `GET /admin/delete?username=carlos`, update `"sub"` to `"administrator"`, sign with the HS256 key again, and send.
11. If the attack fails, repeat from step 5 using a different candidate key from the `sig2n` output.
12. The user `carlos` is deleted.

### Lesson Learned

Applications should never trust the JWT `alg` header supplied by the client to determine which signature verification algorithm to use. The expected signing algorithm must be configured and enforced on the server side.

When using asymmetric algorithms such as RS256, the server must always verify JWTs using the RSA public key and must never interpret that public key as an HMAC secret. Mixing symmetric (HS256) and asymmetric (RS256) algorithms through a generic verification function creates algorithm confusion vulnerabilities.

Even when the public key is not directly exposed, it may be recoverable from observed token signatures using mathematical techniques. Developers should explicitly restrict accepted algorithms, reject unexpected `alg` values, and avoid generic verification methods that automatically select the algorithm from the JWT header.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-jwt-labs/lab-8.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
