Sceawere
Vulnerability Detail
CVE-2026-72860UPDATED Verified Sceawere Triage Sources: NVD / CISA KEV
9router SSRF via Flawed Guard
Vulnerability Metadata
- Severity
- High
- Score / CVSS
- 8.5
- Creation Date
- 4h ago
- Vendor
- decolua
- Product
- 9router
- Attack Type
- Server-Side Request Forgery (SSRF)
- Vector String
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
- Attack Complexity
- LOW
Narrative and Response
Description
The POST /api/provider-nodes/validate route in 9router takes a caller-supplied baseUrl and issues server-side HTTP requests to it, guarding the destination with assertPublicUrl from src/shared/utils/ssrfGuard.js. That guard compares hostname strings only: it resolves no DNS, does not revalidate after a redirect, and its IPv4-mapped IPv6 branch is unreachable. The branch matches ^::ffff:(\d+\.\d+\.\d+\.\d+)$, but the WHATWG URL parser canonicalizes such literals to hextets before the guard runs, so new URL("http://[::ffff:127.0.0.1]/").hostname yields [::ffff:7f00:1] and the pattern is tested against a string it is never handed. Every IPv4-mapped address therefore passes, and http://[::ffff:7f00:1] and http://[::ffff:a9fe:a9fe] reach loopback and link-local metadata addresses; a hostname whose A record points at an internal address passes as well because no resolution occurs. In the custom-embedding branch the upstream response body is truncated to 200 bytes and returned to the caller whenever the upstream status is neither 2xx nor 401 nor 403, which discloses the beginning of internal responses, and the other validation types remain usable for blind internal port scanning through status and timing differences. The caller-supplied apiKey is forwarded to the internal destination as an Authorization Bearer header. A dashboard session is required by default, and none is required when requireLogin is disabled.
Executive Summary
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Technical Details
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Mitigations
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
References
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Additional Metadata
{
"score": "8.5",
"pubDate": "2026-08-20T22:18:05.787Z",
"pubdate": "2026-08-20T22:18:05.787Z",
"executiveSummary": "The 9router application is vulnerable to Server-Side Request Forgery (SSRF) and sensitive data disclosure through the POST /api/provider-nodes/validate route. This flaw stems from inadequate hostname validation within the assertPublicUrl function located in src/shared/utils/ssrfGuard.js. An attacker can exploit this vulnerability to bypass intended network restrictions, access internal network resources, query link-local metadata addresses, and conduct blind internal port scanning. Furthermore, the application truncates and returns upstream response bodies containing non-standard status codes, leading to internal information disclosure, and forwards caller-supplied apiKey credentials as Authorization Bearer headers to the internal destination. Exploitation requires network access to the API route, and while a dashboard session is required by default, this requirement can be bypassed if requireLogin is disabled. The risk implication is significant as it exposes internal infrastructure to unauthorized querying and potential credential leakage.",
"technicalDetails": "The vulnerability resides in the POST /api/provider-nodes/validate route of 9router, which accepts a caller-supplied baseUrl and issues server-side HTTP requests to the specified destination. The security control intended to prevent Server-Side Request Forgery is the assertPublicUrl function implemented in src/shared/utils/ssrfGuard.js. However, this guard suffers from multiple critical architectural and implementation flaws.\nFirst, the guard performs string-only hostname comparisons, resolves no DNS records, and fails to revalidate destinations after following HTTP redirects. Consequently, a hostname whose A record points to an internal address bypasses the check entirely because no resolution is executed prior to the request.\nSecond, the IPv4-mapped IPv6 address validation branch is completely unreachable. The pattern matcher attempts to evaluate expressions matching ^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$, but the WHATWG URL parser canonicalizes such IPv4-mapped literals into hextets before the guard executes. For instance, passing new URL(\"http://[::ffff:127.0.0.1]/\").hostname results in [::ffff:7f00:1], meaning the regular expression is tested against a string format it never receives. As a result, every IPv4-mapped address bypasses the filter, enabling attackers to successfully reach loopback and link-local metadata addresses such as http://[::ffff:7f00:1] and http://[::ffff:a9fe:a9fe].\nThird, in the custom-embedding branch, if the upstream response status is neither 2xx nor 401 nor 403, the application truncates the upstream response body to 200 bytes and returns it directly to the caller, disclosing the initial bytes of internal responses. Other validation types facilitate blind internal port scanning through observable status and timing differences.\nAdditionally, any caller-supplied apiKey is automatically appended and forwarded to the internal destination as an Authorization Bearer header, potentially leaking sensitive authentication material to arbitrary internal services. By default, exploitation requires an active dashboard session, but this prerequisite is eliminated if requireLogin is disabled."
}