Advisory Details

Server-side request forgery (SSRF) via Icon Endpoint Decimal/Hex/Octal IP Bypass

CVSS 3.1:5.8 (Medium)
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
Attack VectorN/A
Attack ComplexityN/A
Privileges RequiredN/A
User InteractionN/A
ScopeN/A
ConfidentialityN/A
IntegrityN/A
AvailabilityN/A
Software:Vaultwarden
Published:19.05.2026
CVE:CVE-2026-47160 ↗
Credits:Reimar Fritz
External Advisory:Check out the external advisory ↗

Summary

The IP validation for the icon fetching endpoint /icons/{domain}/icon.png can be bypassed, resulting in a basic Server-side request forgery (SSRF) vulnerability. The http_request_block_non_global_ips protection checks IPs using Rust’s IpAddr::from_str(), which does not parse decimal, hex, or octal IP representations. However, the underlying DNS/HTTP resolver (glibc/Hickory) resolves them.

This SSRF allows an attacker to perform HTTP/HTTPS requests from the Vaultwarden server to arbitrary (internal) IPs, but only responds with parsed favicon images (not raw response bodies), limiting this to a blind internal network/port discovery via timing and response-size differences.

Details

Vaultwarden runs as two Docker containers:

Root cause (two-stage bypass):

  1. Pre-connect filter bypass (src/http_client.rs:62-69): should_block_address() uses Rust’s IpAddr::from_str() which only recognizes dotted-decimal notation. Decimal/hex/octal representations are not parsed as IPs and pass through unchecked.

  2. Post-resolve check bypass (src/http_client.rs:229): The post_resolve() function checks resolved IPs, but it is only called from the custom DNS resolver (CustomDnsResolver::resolve_domain). When the URL host is a numeric literal, the Rust url crate (WHATWG URL Standard compliant) parses it directly as an IPv4 address. Reqwest then connects to the IP without invoking the custom DNS resolver at all, post_resolve() is never called.

Bypass payloads that successfully fetched from internal IPs:

PoC

Basic PoC:

From the logs:

[2026-04-02 09:28:04.648][request][INFO] GET /icons/2130706433/icon.png
[2026-04-02 09:28:04.651][response][INFO] (icon_internal) GET /icons/<domain>/icon.png => 200 OK
[2026-04-02 09:28:08.371][request][INFO] GET /icons/127.0.0.1/icon.png
[2026-04-02 09:28:08.371][vaultwarden::api::icons][WARN] Blocked address: 127.0.0.1
[2026-04-02 09:28:08.371][response][INFO] (icon_internal) GET /icons/<domain>/icon.png => 200 OK

The same applies to other resources, that are only internally available. An exemplary, additional nginx container on a Docker internal: true network, serving a favicon with no published ports, only reachable from the vaultwarden container, not from nginx or the outside, yet the decimal IP bypass (2886991875 for 172.20.0.3) successfully fetches the favicon through the icon endpoint.

From the logs:

[2026-04-02 09:40:43.433][request][INFO] GET /icons/172.19.0.4/icon.png
[2026-04-02 09:40:43.433][vaultwarden::api::icons][WARN] Blocked address: 172.19.0.4
[2026-04-02 09:40:43.433][response][INFO] (icon_internal) GET /icons/<domain>/icon.png => 200 OK
[2026-04-02 09:40:44.983][request][INFO] GET /icons/2886926340/icon.png
[2026-04-02 09:40:44.985][response][INFO] (icon_internal) GET /icons/<domain>/icon.png => 200 OK

Impact

An unauthenticated attacker can:

Könnte deine Anwendung auch Lücken haben?

In unserem Hacking Cult Bootcamp durchläufst du in 4 Wochen einen strukturierten Security-Check. Von Grundlagenwissen, um zu prüfen, wo dein Team wirklich steht, bis hin zum konkreten Schwachstellen-Scan deiner Webanwendung. Und das komplett kostenlos!

Melde dich!

Hacking Cult GmbH

Gerolfinger Str. 106
85049 Ingolstadt

+49 (841) 9937 3456
ops[LOESCH-MICH-SPAMSCHUTZ]@[LOESCH-MICH-AUCH]hackingcult.de

LinkedIn Unternehmensseite
Facebook Account
Hacking Cult Youtube Channel
Hacking Cult Instagram account