CVE-2026-72860: 9router Server-Side Request Forgery via /api/provider-nodes/validate Because the IPv4-Mapped IPv6 Denylist Check Is Unreachable

Published Aug 20, 2026
·
Updated

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.

Affected Software

1 affected component
9Router

Event History

Aug 20, 2026
CVE Published
via MITRE·09:35 PM
Data Sourced
via MITRE·09:35 PM
DescriptionSeverityWeakness

Frequently Asked Questions

1

Who can exploit this issue?

An attacker needs privileges sufficient to call the POST /api/provider-nodes/validate endpoint and control its baseUrl value. No user interaction is required.

2

Which destinations can bypass the URL guard?

IPv4-mapped IPv6 literals can bypass the denylist because the URL parser canonicalizes them before the guard checks them; the supplied examples reach loopback and link-local metadata addresses. Hostnames that resolve to internal addresses also pass because the guard does not perform DNS resolution.

3

Can this disclose data, or is it limited to blind requests?

For custom embeddings, if the upstream response status is not 2xx, 401, or 403, the endpoint returns up to the first 200 bytes of the upstream response body. Other validation types can still be used for blind internal port scanning.

4

Are redirects protected by the guard?

No. The destination is not revalidated after a redirect, so a request initially accepted by the guard can be redirected to another location.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203