mediumVulnerability

CVE-2026-47076

### Summary `hackney_url:normalize/2` URL-decodes the host component of a parsed URL, but the caller's SSRF allowlist runs before normalization using OTP's `uri_string:parse/1` and `inet:parse_address/1`, neither of which decodes percent-escapes in hostnames. A URL like `http://%31%32%37%2E%30%2E%30%2E%31/` presents an encoded, non-IP-looking host to the validator, which passes the allowlist check; hackney's normalizer then decodes it to `127.0.0.1` and connects to loopback. Because `hackney:request/5` always calls `normalize/2` with no opt-out, every request path that accepts a binary or list URL is affected. This is a parser-differential SSRF in the same class as CVE-2025-1211, but in a different function. ### Details In `src/hackney_url.erl` (lines 161–186), `normalize/2` checks whether the parsed host is already a dotted-quad or IPv6 literal via `inet_parse:address/1`. Percent-encoded forms like `%31%32%37%2E%30%2E%30%2E%31` fail that check and fall into the catch-all branch, where `urldecode/1` decodes the host before passing it to IDNA conversion: ```erlang Host1 = binary_to_list( urldecode(unicode:characters_to_binary(Host0)) ), ``` The decoded host (`"127.0.0.1"`) replaces the original in the returned `#hackney_url{}` record. `hackney:request/5` at `src/hackney.erl:463` always calls `normalize/2`, so the decoded host is what `do_dispatch/1` and `add_host_header/2` ultimately use. The on-wire `Host:` header and the TCP connect target both reflect the decoded value. The same payload pattern reaches the AWS/GCP/Azure IMDS (`169.254.169.254`), RFC1918 ranges, and any `localhost` admin endpoint. The 1.21.0 patch for CVE-2025-1211 fixed a separate differential in `parse_url/1` and did not touch `normalize/2`. ### PoC 1. Validate the URL with the canonical Erlang SSRF allowlist: `uri_string:parse/1` returns host `<<"%31%32%37%2E%30%2E%30%2E%31">>`, `inet:parse_address/1` returns `{error, einval}`, so the allowlist accepts it. 2. Pass the

Properties

ghsa_id
GHSA-pj7v-xfvx-wmjq
severity
medium
summary
Hackney has SSRF allowlist bypass in hackney_url:normalize/2 via percent-encoded host
epss_score
0.00229
cve_id
CVE-2026-47076
is_ghsa_only
false
ghsa_published
2026-06-26T21:54:55Z
source_url
https://github.com/advisories/GHSA-pj7v-xfvx-wmjq
epss_percentile
0.1368
ghsa_updated
2026-06-26T21:54:57Z

Related Entities (6)

ENRICHED_BY (1)

[Source]FIRST EPSS

REPORTED_BY (1)

[Source]GitHub Advisory Database

VULNERABLE_TO (1)

[Software]erlang/hackney

AFFECTS (1)

[Software]erlang/hackney

HAS_WEAKNESS (2)

[Weakness]Server-Side Request Forgery (SSRF)
[Weakness]Interpretation Conflict

Explore deeper with Ninja Signal's threat intelligence graph