Full Report
Server side request forgery (SSRF) is a popular and impactful vulnerability when used correctly. In order to prevent this attack, processing is done on the URLs to ensure that no internal URLs are used. The title of this post says it all: switching protocols to bypass protections. One common bypass is reaching out to a public domain then redirecting to an internal IP. The authors of this post had found this multiple times then asked them to use the anti-SSRF libraries ssrfFilter which appeared to solve the problem. When messing around with the library, going from HTTP to HTTP was blocked for localhost redirects. However, going from HTTPs to HTTP (or vice verse) on localhost wasn't blocked. What happened? Within the request library, whenever the protocol is changed the request agent is deleted to ensure the right client is used. However, the SSRF prevention is based on the agents createConnection event handler! So, the SSRF mitigation strategy doesn't work since the hook is never called. Overall, a fairly crazy/weird bypass in the protections for SSRF issues. Sometimes, dynamic blackbox testing with weird things is more fruitful than seeing the code. There's no way anybody could have found this reading the code as a security researcher.
Analysis Summary
# Vulnerability: SSRF Cross-Protocol Redirect Bypass in 'request' Library
## CVE Details
- **CVE ID:** CVE-2023-28155
- **CVSS Score:** Not explicitly listed in the article (typically High for SSRF leading to internal access)
- **CWE:** CWE-918 (Server-Side Request Forgery)
## Affected Systems
- **Products:** `request` (popular Node.js HTTP client library)
- **Versions:** All versions up to and including v2.88.2 (Note: The `request` library is officially deprecated)
- **Configurations:** Systems using the `request` library in conjunction with anti-SSRF agents/filters (like `ssrf-req-filter`) that rely on the `createConnection` event handler.
## Vulnerability Description
The vulnerability exists in how the `request` library handles HTTP(S) redirections. When a request is redirected to a different protocol (e.g., from HTTPS to HTTP or vice versa), the library's internal logic (`lib/redirect.js`) deletes the `request.agent`. This is done because the native Node.js `http.Agent` is not compatible across both protocols.
However, many SSRF mitigation libraries (such as `ssrf-req-filter`) work by injecting a custom agent that intercepts the `createConnection` event to validate the destination IP address. When the library deletes the agent during a cross-protocol redirect, it also removes the security hook. Consequently, the second request (the redirect) proceeds without any SSRF filtering, allowing an attacker to access internal hosts or `localhost`.
## Exploitation
- **Status:** PoC available (demonstrated in disclosure)
- **Complexity:** Low
- **Attack Vector:** Network
- **Mechanism:** An attacker provides a URL to an external server they control. That server then issues a 302 redirect with a protocol change (HTTPS -> HTTP) pointing to an internal resource (e.g., `http://127.0.0.1/admin`).
## Impact
- **Confidentiality:** High (Access to internal services, metadata endpoints, and unauthorized data retrieval)
- **Integrity:** Medium to High (Potential to perform state-changing actions on internal APIs)
- **Availability:** Low to Medium (Depends on the internal services reached)
## Remediation
### Patches
- The `request` library is **deprecated** and unmaintained. While a Pull Request (#3444) was submitted by the researcher, official updates are unlikely. Users are strongly encouraged to migrate to maintained libraries.
### Workarounds
- **Migrate Libraries:** Move from `request` to modern alternatives like `axios`, `got`, or `undici`.
- **Disable Redirects:** Manually set `followRedirect: false` in the request options and handle redirects in application logic where they can be re-validated.
- **Manual Validation:** Re-validate the `Location` header manually before following any redirect.
## Detection
- **Indicators of Compromise:** Unusual internal network traffic emanating from the web server; logs showing 30x redirects from external domains to internal IP addresses (127.0.0.1, 192.168.x.x, 169.254.169.254).
- **Detection Methods:** Dynamic blackbox testing specifically targeting protocol-switching redirects (HTTPS to HTTP).
## References
- **Doyensec Blog:** hxxps[://]blog[.]doyensec[.]com/2023/03/16/ssrf-bypass[.]html
- **GitHub Issue:** hxxps[://]github[.]com/request/request/issues/3442
- **NPM ssrf-req-filter:** hxxps[://]www[.]npmjs[.]com/package/ssrf-req-filter
- **PortSwigger SSRF Guide:** hxxps[://]portswigger[.]net/web-security/ssrf