CVE-2026-47076
mediumpriority · track · 26EPSS 0.002 · 14 %ileEUUSEPSS · scored 2026-10-27
Interpretation Conflict vulnerability in benoitc hackney allows Server Side Request Forgery. hackney_url:normalize/2 URL-decodes the host component after the URL has been parsed into a #hackney_url{} record. OTP's uri_string:parse/1 and inet:parse_address/1 do not decode percent-escapes in the host, so a URL such as http://%31%32%37%2E%30%2E%30%2E%31/ is seen by a caller's allowlist validator with host %31%32%37%2E%30%2E%30%2E%31 (not an IP address), which passes the allowlist check. hackney's normalizer then decodes the host to 127.0.0.1 and opens a TCP connection to loopback. Because hackney:request/5 always calls hackney_url:normalize/2 with no opt-out, every request that takes a binary or list URL is affected. The same technique reaches cloud instance metadata services (169.254.169.254), RFC1918 networks, and any admin interface listening on localhost. This issue affects hackney: from 0.13.0 before 4.0.1.
cvss
Technical severity, 0–10. One row per scoring source.
base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · low–medium · 3.6–6.9
ssvc
A stakeholder decision — act, attend, or track — from exploitation and impact.
weaknesses
The CWE weakness classes this flaw belongs to.
affected products (4)
Products and version ranges known to be affected.
advisories (2)
Vendor and ecosystem advisories describing this.
- GHSA-pj7v-xfvx-wmjqHackney has SSRF allowlist bypass in hackney_url:normalize/2 via percent-encoded host2026-06-26ghsa · osvUS
### 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 same URL to `hackney:get/1`. 3. hackney's `normalize/2` decodes the host to `"127.0.0.1"` and connects to `127.0.0.1:80`. The internal service receives the request with `Host: 127.0.0.1`. ### Impact Unauthenticated SSRF bypassing the canonical Erlang allowlist pattern. Affects hackney 0.13.0 through 4.0.0 for any application that accepts attacker-supplied URLs. Targets include cloud IMDS endpoints, `localhost` admin interfaces, and RFC1918 backends. CVSS v4.0: **6.9 (MEDIUM)**. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/4d725507588942fd00efca15b86da3273656510a * Patch commit: https://github.com/benoitc/hackney/commit/452620a92ec1da2e6b4862a049a2a4f04b42068f
- EEF-CVE-2026-47076SSRF allowlist bypass via percent-encoded host in hackney2026-05-25vendor · osvUS
## Summary Interpretation Conflict vulnerability in benoitc hackney allows Server Side Request Forgery. hackney\_url:normalize/2 URL-decodes the host component after the URL has been parsed into a #hackney\_url{} record. OTP's uri\_string:parse/1 and inet:parse\_address/1 do not decode percent-escapes in the host, so a URL such as http://%31%32%37%2E%30%2E%30%2E%31/ is seen by a caller's allowlist validator with host %31%32%37%2E%30%2E%30%2E%31 (not an IP address), which passes the allowlist check. hackney's normalizer then decodes the host to 127.0.0.1 and opens a TCP connection to loopback. Because hackney:request/5 always calls hackney\_url:normalize/2 with no opt-out, every request that takes a binary or list URL is affected. The same technique reaches cloud instance metadata services (169.254.169.254), RFC1918 networks, and any admin interface listening on localhost. This issue affects hackney: from 0.13.0 before 4.0.1.
also known as (5)
Other names and identifiers for this entity.
sources
Which sources assert this record, and when.
references (14)
External citations — patches, advisories, analysis.
- https://access.redhat.com/security/cve/cve-2026-47076cnnvd
- https://cna.erlef.org/cves/CVE-2026-47076.htmlcnnvd
- https://github.com/benoitc/hackney/commit/452620a92ec1da2e6b4862a049a2a4f04b42068fcnnvd
- https://github.com/benoitc/hackney/releasesPatchcnnvd
- https://github.com/benoitc/hackney/security/advisories/GHSA-pj7v-xfvx-wmjqcnnvd
- https://osv.dev/vulnerability/EEF-CVE-2026-47076cnnvd
- https://cna.erlef.org/cves/CVE-2026-47076.htmlenisa_euvd
- https://github.com/benoitc/hackney/commit/452620a92ec1da2e6b4862a049a2a4f04b42068fenisa_euvd
Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.
Free scan