> 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-6.md).

# lab-6

## JWT Authentication Bypass via Kid Header Path Traversal

**Difficulty:** Practitioner

### Lab Description

This lab uses a JWT-based mechanism for handling sessions. To verify the signature, the server uses the `kid` parameter in the JWT header to fetch the relevant key from its filesystem.

**Objective:** Forge a JWT that gives you access to the admin panel at `/admin`, then delete the user `carlos`.

**Credentials:** `wiener:peter`

### Root Cause

The application trusted the user-controlled `kid` header parameter to determine the verification key used for validating JWT signatures. Instead of restricting `kid` to predefined key identifiers, the server treated its value as a filesystem path without proper validation or sanitisation.

This allowed a path traversal attack by supplying `../../../../../../../dev/null` as the `kid` value. The server read `/dev/null` as the verification key file. Since `/dev/null` is an empty file on Linux systems, the verification secret became an empty string. By signing a forged JWT with an empty string as the HMAC secret, the attacker produced a signature that matched the server's verification process — allowing arbitrary JWT claims to be trusted.

### Exploitation

1. Intercept the authenticated JWT and send the `GET /admin` request to Burp Repeater.
2. In the **JWT Editor** tab, generate a new symmetric (HMAC) signing key.
3. Edit the generated JWK and replace the value of the `k` property with an empty string — this creates a signing key that represents an empty HMAC secret.
4. Modify the JWT header, changing the `kid` parameter to a path traversal payload:

   ```
   ../../../../../../../dev/null
   ```
5. Modify the JWT payload, changing `"sub"` from `"wiener"` to `"administrator"`.
6. Sign the modified JWT using the symmetric key with the empty secret.
7. Send the forged JWT. The server interprets the `kid` value as a file path, opens `/dev/null`, obtains an empty string as the verification key, and successfully validates the attacker-generated signature.
8. The server trusts the modified payload, authenticates the attacker as `administrator`, and grants access to `/admin`.
9. Delete the user `carlos` to complete the lab.

### Lesson Learned

Applications must never treat user-controlled JWT header parameters such as `kid` as filesystem paths or other directly accessible resources. The `kid` value should only reference predefined key identifiers that are securely mapped to trusted verification keys on the server side.

The server should validate `kid` against an allowlist of expected values and reject any path traversal sequences or unexpected input. User input must never influence file paths used during cryptographic operations. When using symmetric algorithms such as HS256, the verification secret must always originate from secure server-side configuration — not from external files specified by client input.


---

# 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-6.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.
