Skip to content
WebHard

Exploiting Server-Side Parameter Pollution in a REST URL

Platform: PortSwigger Web Security Academy Difficulty: Expert Category: Server-Side Parameter Pollution / REST API Security Primary Tool: Burp Suite Environment: PortSwigger Web Security Academy Lab

Exploiting Server-Side Parameter Pollution in a REST URL

1. Overview

This lab demonstrated a server-side parameter pollution vulnerability in a password-reset workflow.

The objective was to obtain a password-reset token for the administrator account, use the token to reset the administrator's password, authenticate as the administrator, and delete the carlos user.

Rather than directly attacking the password-reset functionality, the investigation focused on understanding how the application processed the supplied username parameter.

The key discovery was that the application appeared to incorporate the user-controlled username value into a server-side REST API request.

This created an opportunity to manipulate the path of the server-side request using URL syntax and path traversal.

The investigation ultimately revealed an API definition and exposed an internal endpoint structured as:

1/api/internal/v1/users/{username}/field/{field}

This endpoint provided an important clue about how the backend was processing user information.


2. Objective

The lab's objective was to:

  1. Investigate the password-reset functionality.
  2. Determine how the username parameter was processed.
  3. Identify whether the parameter influenced a server-side URL.
  4. Discover the internal REST API structure.
  5. Access the password-reset token for the administrator.
  6. Reset the administrator's password.
  7. Authenticate as the administrator.
  8. Delete the carlos user.

3. Tools Used

Burp Suite

Burp Suite was used to:

  • intercept HTTP requests,
  • inspect HTTP history,
  • modify request parameters,
  • send requests to Repeater,
  • compare server responses,
  • investigate URL/path behavior,
  • test path traversal,
  • and observe error messages.

Burp Browser

The built-in browser was used to interact with the vulnerable password-reset functionality and later access the password-reset URL.


4. Initial Reconnaissance

I began by using Burp's browser to trigger the password-reset functionality for the administrator account.

The application generated a request similar to:

1POST /forgot-password HTTP/1.1
2Host: <LAB-HOST>
3
4username=administrator

The request contained:

1username=administrator

This immediately identified username as a user-controlled input.

The first goal was not to exploit it immediately, but to understand how the application used this value.


5. Moving the Request to Repeater

I sent the POST /forgot-password request to Burp Repeater.

Repeater was useful because it allowed the request to be modified and resent repeatedly while observing how small changes affected the application's response.

The original request was first resent without modification to establish a baseline.

The response was consistent with the original password-reset request.

This established:

1Normal input
2
3administrator
4
5Normal response

I could now begin experimenting with the username parameter.


6. Investigating the Username Parameter

The first test was to URL-encode a # character.

1administrator%23

%23 represents:

1#

The application returned an Invalid route error.

This was interesting because changing only the username caused what appeared to be a routing-related error.

At this point, I formed a hypothesis:

The username may not simply be used as a database lookup value. It may be inserted into a URL or REST API path somewhere on the server side.

This was the first major shift in my investigation.


7. Testing URL Semantics

I tested additional characters that have special meaning within URLs.

Test 1 — Fragment delimiter

1administrator%23

Result:

1Invalid route

Test 2 — Query-string delimiter

I changed the value to:

1administrator%3F

where:

1%3F = ?

Again, the application returned:

1Invalid route

This strengthened the hypothesis that the input was being interpreted as part of a URL.

The important observation was:

A parameter that should logically represent a username was influencing routing behavior.


8. Testing Relative Paths

Next, I tested:

1./administrator

The application returned the original response.

This was significant because . represents the current path segment.

I then tested:

1../administrator

The application returned:

1Invalid route

This suggested that the application was processing the supplied username as part of a path.

The investigation had now moved from:

1username manipulation

toward:

1URL/path manipulation

9. Understanding the Vulnerability

At this point, the emerging model was:

1Browser / Burp
2
3 │ POST /forgot-password
4 │ username=administrator
5
6Web Application
7
8 │ uses username
9 │ to construct another URL
10
11Internal REST API

The important realization was that there appeared to be another server-side request occurring behind the password-reset functionality.

The user's username was potentially influencing the path of that internal request.

Conceptually:

1/api/internal/v1/users/{username}/...

If:

1username = administrator

the resulting path might resemble:

1/api/internal/v1/users/administrator/...

But if the username contains:

1../

the resulting URL path may be interpreted differently.

This is why path traversal became relevant.


10. Navigating the API Path

The next goal was to determine how far the supplied path could be manipulated.

I tested:

1../%23

and then incrementally added more parent-directory traversal sequences.

Eventually, I reached:

1../../../../%23

At this point, the server returned a different response indicating that I had navigated outside the expected API root.

This was important evidence.

It suggested that the application was actually interpreting the ../ sequences as path traversal rather than treating them as ordinary username characters.

The conceptual behavior was:

1/api/internal/v1/users/../
2
3 move to parent

Multiple traversal sequences could therefore move progressively upward through the URL path.


11. Discovering the API Definition

Once I had evidence that the API path could be manipulated, I tested for common API-definition files.

One successful request used:

1../../../../openapi.json%23

This resulted in an error message containing useful API information.

The response revealed an endpoint structured as:

1/api/internal/v1/users/{username}/field/{field}

This was a major breakthrough.

Instead of guessing the internal API structure, I now had an API definition describing how the endpoint was designed.


12. Understanding the Discovered Endpoint

The endpoint:

1/api/internal/v1/users/{username}/field/{field}

contains two dynamic components:

1username
2field

Conceptually:

1/api/internal/v1/users/
2
3 └── {username}
4
5/field/
6
7 └── {field}

This suggested that the API could retrieve a particular field belonging to a particular user.

For example:

1/api/internal/v1/users/administrator/field/email

could conceptually mean:

Retrieve the email field belonging to administrator.

This was important because it revealed that the API wasn't simply retrieving a complete user record.

It was exposing specific user fields.


13. Testing the Field Parameter

I then attempted to manipulate the path so that the server-side request would contain:

1administrator/field/foo

The resulting username value was:

1administrator/field/foo%23

The API returned an error explaining that the requested field was invalid.

This was useful because the error revealed that the API recognized the injected structure and was actually processing the field parameter.

I then tested:

1administrator/field/email%23

The application returned the original response.

This indicated that:

1email

was a valid field.

At this stage, the hypothesis was becoming much stronger:

1User-controlled username
2
3Inserted into server-side URL
4
5Can inject additional path segments
6
7Internal REST API recognizes those segments

14. Investigating the Password Reset Token

I then reviewed the JavaScript file associated with the password-reset functionality:

1/static/js/forgotPassword.js

The JavaScript revealed the password-reset endpoint:

1/forgot-password?passwordResetToken=${resetToken}

This was another important discovery.

It established that the application expected a value called:

1passwordResetToken

to be supplied to the password-reset endpoint.

The next question became:

Can the internal API return the passwordResetToken field?


15. API Version Discovery

I tested:

1administrator/field/passwordResetToken%23

The application returned an error stating that this field was not supported by the current API version.

This was an important clue.

The API definition had identified:

1/api/internal/v1/users/{username}/field/{field}

but the application indicated that the requested field wasn't available in that version.

Instead of assuming the field did not exist, I considered another possibility:

The field might be supported by another API version.

This led to another path manipulation test.


16. Changing the API Version

The server-side path was manipulated to target the earlier API version:

1../../v1/users/administrator/field/passwordResetToken%23

This time, the application returned the password-reset token.

This was the critical result of the exploitation chain.

The progression was:

1username parameter
2
3Server-side URL construction
4
5Path traversal
6
7API definition discovery
8
9Internal endpoint discovery
10
11Field manipulation
12
13API version manipulation
14
15passwordResetToken

The vulnerability therefore allowed the user-controlled parameter to influence the internal REST API request far beyond its intended purpose.


17. Password Reset

The recovered password-reset token was then supplied to the password-reset endpoint:

1/forgot-password?passwordResetToken=<TOKEN>

This opened the password-reset functionality.

I set a new password for the administrator account.


18. Authentication and Impact

I then logged in using:

1Username:
2administrator
3
4Password:
5<new password>

After successfully authenticating as the administrator, I accessed the administrative functionality.

The final objective was to delete:

1carlos

Successfully deleting the user demonstrated the impact of the vulnerability.

The attack therefore progressed from a seemingly ordinary username parameter to administrative account takeover.


19. Attack Chain

The entire exploit can be summarized as:

1START
2
3
4 POST /forgot-password
5 username=administrator
6
7
8 Investigate parameter
9
10
11 Server-side URL manipulation
12
13
14 Path traversal
15
16
17 Escape expected API path
18
19
20 Discover openapi.json
21
22
23 Discover internal REST endpoint
24
25
26 /api/internal/v1/users/{username}/field/{field}
27
28
29 Inject field parameter
30
31
32 Discover API version behavior
33
34
35 Request passwordResetToken
36
37
38 Obtain token
39
40
41 Reset administrator password
42
43
44 Login as administrator
45
46
47 Delete carlos
48
49
50 SOLVED

20. Key Payloads and Requests

The important values tested during the investigation included:

1administrator
2administrator%23
3administrator%3F
4./administrator
5../administrator
6../%23
7../../../../%23
8../../../../openapi.json%23
9administrator/field/foo%23
10administrator/field/email%23
11administrator/field/passwordResetToken%23
12../../v1/users/administrator/field/passwordResetToken%23

The important discovery was not any individual payload.

The important discovery was why each payload was tested.


21. What I Learned

Server-side requests

A web application can receive a request from the browser and then make another request to an internal API.

1Browser
2
3Web application
4
5Internal API

Therefore, an input parameter can potentially influence a request that the user never directly sees.


Path traversal

The sequence:

1../

represents the parent path segment.

For example:

1/api/v1/users/../admin

can normalize conceptually to:

1/api/v1/admin

The important security issue occurs when an application allows user-controlled input to influence a path without properly restricting its destination.


URL encoding

I also reinforced the importance of understanding URL encoding:

1%23 = #
2%3F = ?

Encoded characters can still have special meaning once decoded or interpreted in the appropriate context.


API enumeration through errors

Error messages were useful sources of information.

Rather than treating an error as simply a failed request, I used changes in error behavior as evidence about what the backend was doing.

For example:

1Invalid route

helped suggest that the supplied input was influencing routing.

Later:

1Invalid field

provided evidence that the internal API was actually interpreting an injected field component.


API documentation as an attack-surface map

The discovered openapi.json definition was particularly valuable because it revealed the structure of an internal API.

Instead of blindly guessing endpoints, I could reason from the API definition:

1/api/internal/v1/users/{username}/field/{field}

This demonstrated why exposed API specifications can become valuable reconnaissance material.


22. Root Cause

The underlying problem was not simply that ../ existed.

The deeper issue was that user-controlled input was incorporated into a server-side REST URL without sufficiently restricting what that input could represent.

Conceptually:

1const username = req.body.username;
2
3const url =
4 `http://internal-api/api/internal/v1/users/${username}`;
5
6fetch(url);

The application expected:

1username = administrator

but did not sufficiently ensure that the value remained only a username.

An attacker could instead influence the structure of the server-side URL.


23. Defensive Considerations

A secure implementation should avoid blindly concatenating user-controlled values into URLs.

Potential defenses include:

  • strict allowlisting of expected username formats,
  • validating input according to its intended type,
  • avoiding user-controlled URL path construction,
  • safely encoding path components,
  • canonicalizing and validating paths where path input is genuinely required,
  • restricting internal API access,
  • authenticating internal API requests,
  • preventing unnecessary exposure of internal API documentation,
  • avoiding overly descriptive error messages,
  • and ensuring sensitive fields cannot be requested simply by changing a path parameter.

The most important principle is:

Validate data according to what it is supposed to represent, rather than allowing it to redefine the structure of the request.


24. Skills Demonstrated

Web Security

  • Server-side parameter pollution
  • REST API security
  • Path traversal
  • Authentication-flow analysis
  • Password-reset security
  • API enumeration

Burp Suite

  • Proxy
  • HTTP History
  • Repeater
  • Request manipulation
  • Response analysis

Web Technologies

  • HTTP
  • REST APIs
  • URL encoding
  • URL/path semantics
  • API specifications
  • JavaScript analysis

Security Methodology

  • Reconnaissance
  • Hypothesis formation
  • Controlled experimentation
  • Error-based information gathering
  • Attack-surface discovery
  • Exploit chaining
  • Impact verification

25. Final Reflection

The most valuable lesson from this lab was not memorizing a particular path-traversal payload.

The important lesson was learning to follow data flow.

The investigation started with:

1username=administrator

and gradually established that the value could influence:

1server-side URL
2
3REST API path
4
5API endpoint
6
7requested field
8
9password reset token

The vulnerability became apparent only after connecting those observations together.

This reinforced a key penetration-testing principle:

When an input behaves unexpectedly, don't immediately search for a payload. First determine where the input travels, how it is interpreted, and what the application does with it.