CVE-2026-47076: Hackney Remote Code Execution Vulnerability
MODERATECVE-2026-47076 is a MODERATE remote code execution vulnerability (CWE-436: Interpretation Conflict) affecting Hackney libraries in the Hex ecosystem. The issue involves normalize/2 via percent-encoded host. Remediation is available by upgrading affected packages to version 4.0.1.
CVE-2026-47076 at a Glance
How to Fix CVE-2026-47076
To remediate this vulnerability, upgrade all affected Hackney dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade hackney to 4.0.1
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for hackney
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-47076, inspect your project dependencies for Hackney:
inspect dependencies for hackney
Analyze the terminal output to locate any version of Hackney in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.0.1), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-436: Interpretation Conflict, where product a handles inputs or steps differently than product b, which causes a to perform incorrect actions based on its perception of b's state. In Hackney, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-47076 Affected Hackney Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
hackney
|
Hex |
≥ 0.13.0
< 4.0.1
|
4.0.1
|
References
Frequently Asked Questions
What is CVE-2026-47076?
Which Hackney versions are affected?
What version fixes CVE-2026-47076?
Is hackney affected?
What CWE is associated with CVE-2026-47076?
How can I check Hex dependencies for CVE-2026-47076?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-pj7v-xfvx-wmjq",
"modified" : "2026-06-26T21:54:55Z",
"published" : "2026-06-26T21:54:55Z",
"aliases" : [ "CVE-2026-47076" ],
"summary" : "Hackney has SSRF allowlist bypass in hackney_url:normalize/2 via percent-encoded host",
"details" : "### Summary\n\n`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.\n\n### Details\n\nIn `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:\n\n```erlang\nHost1 = binary_to_list(\n urldecode(unicode:characters_to_binary(Host0))\n ),\n```\n\nThe 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.\n\nThe 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`.\n\n### PoC\n\n1. 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.\n2. Pass the same URL to `hackney:get/1`.\n3. 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`.\n\n### Impact\n\nUnauthenticated 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)**.\n\n## Resources\n\n* Introduction commit: https://github.com/benoitc/hackney/commit/4d725507588942fd00efca15b86da3273656510a\n* Patch commit: https://github.com/benoitc/hackney/commit/452620a92ec1da2e6b4862a049a2a4f04b42068f",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Hex",
"name" : "hackney"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0.13.0"
}, {
"fixed" : "4.0.1"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/benoitc/hackney/security/advisories/GHSA-pj7v-xfvx-wmjq"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-47076"
}, {
"type" : "WEB",
"url" : "https://github.com/benoitc/hackney/commit/452620a92ec1da2e6b4862a049a2a4f04b42068f"
}, {
"type" : "WEB",
"url" : "https://cna.erlef.org/cves/CVE-2026-47076.html"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/benoitc/hackney"
}, {
"type" : "WEB",
"url" : "https://osv.dev/vulnerability/EEF-CVE-2026-47076"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-436", "CWE-918" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-06-26T21:54:55Z",
"nvd_published_at" : "2026-05-25T15:16:22Z"
}
}