CVE-2026-47069 Overview
CVE-2026-47069 is a Carriage Return Line Feed (CRLF) injection vulnerability in benoitc/hackney, a widely used HTTP client library for Erlang. The flaw exists in the hackney_cookie:setcookie/3 function in src/hackney_cookie.erl. While the function validates Name and Value arguments against CRLF and control characters, it concatenates the domain and path options verbatim into the output iolist without equivalent checks. An attacker who controls either option can inject literal CRLF sequences and arbitrary Set-Cookie headers, enabling HTTP Response Splitting [CWE-93]. The issue affects hackney versions from 0.9.0 before 4.0.1.
Critical Impact
An attacker controlling a request-derived Host header or path forwarded as the cookie domain or path can inject additional Set-Cookie headers into the HTTP response.
Affected Products
- benoitc hackney from 0.9.0 before 4.0.1
- Erlang applications using hackney for HTTP client cookie handling
- Downstream libraries that propagate request-derived Host headers or paths to hackney cookie options
Discovery Timeline
- 2026-05-25 - CVE-2026-47069 published to NVD
- 2026-05-27 - Last updated in NVD database
Technical Details for CVE-2026-47069
Vulnerability Analysis
The vulnerability resides in hackney_cookie:setcookie/3, the function responsible for serializing cookie attributes into a Set-Cookie header string. The function applies CRLF and control-character validation to the cookie Name and Value, but treats the domain and path options as trusted iolist fragments. The serializer concatenates them directly into the output as ; Domain=<Domain> and ; Path=<Path>. Because these option values can originate from request-derived data such as the inbound Host header or request path, an attacker can supply bytes including \r, \n, or ; to terminate the current header and append additional Set-Cookie attributes or unrelated headers. The result is HTTP Response Splitting, where the attacker injects content into the response stream produced by downstream code that forwards the constructed header.
Root Cause
The root cause is inconsistent input neutralization. Only Name and Value are scanned for line-terminating and control bytes; domain and path are concatenated without sanitization. Erlang's iolist handling preserves the attacker-supplied bytes intact, so any CRLF sequence survives serialization.
Attack Vector
Exploitation requires that an upstream application forward attacker-controlled input — typically a Host header or request path — into the domain or path cookie options passed to hackney_cookie:setcookie/3. The attacker supplies a value containing \r\n followed by an injected Set-Cookie header or other HTTP header content. The injected bytes appear in the constructed response, enabling cache poisoning, session fixation via attacker-controlled cookies, or response manipulation.
// Patch excerpt from src/hackney_cookie.erl (GHSA-mp55-p8c9-rfw2)
end,
DomainBin = case lists:keyfind(domain, 1, Opts) of
false -> <<>>;
- {_, Domain} -> [<<"; Domain=">>, Domain]
+ {_, Domain} ->
+ %% GHSA-mp55: Name/Value are guarded above; Domain and
+ %% Path must reject the same line-terminating bytes (and
+ %% ';', which would start a new attribute) so a
+ %% request-derived domain/path cannot inject a second
+ %% Set-Cookie header.
+ nomatch = binary:match(iolist_to_binary(Domain),
+ [<<$;>>, <<$\s>>, <<$\t>>, <<$\r>>,
+ <<$\n>>, <<$\013>>, <<$\014>>, <<0>>]),
+ [<<"; Domain=">>, Domain]
end,
PathBin = case lists:keyfind(path, 1, Opts) of
false -> <<>>;
- {_, Path} -> [<<"; Path=">>, Path]
+ {_, Path} ->
+ nomatch = binary:match(iolist_to_binary(Path),
+ [<<$;>>, <<$\r>>, <<$\n>>,
+ <<$\013>>, <<$\014>>, <<0>>]),
+ [<<"; Path=">>, Path]
end,
Source: GitHub Commit 8e02b99. This patch enforces a binary:match check on both Domain and Path, rejecting ;, whitespace, CR, LF, vertical tab, form feed, and NUL bytes before concatenating them into the output.
Detection Methods for CVE-2026-47069
Indicators of Compromise
- HTTP responses containing multiple Set-Cookie headers where only one was expected, particularly with Domain or Path attributes carrying unusual byte sequences.
- Application logs showing Host header or request path values containing \r, \n, or ; characters being passed to hackney cookie functions.
- Web Application Firewall (WAF) alerts on inbound requests with encoded CRLF sequences (%0d%0a) in Host headers or paths.
Detection Strategies
- Inventory Erlang projects and dependency manifests (rebar.config, mix.exs) for hackney versions below 4.0.1.
- Add static analysis rules to flag calls to hackney_cookie:setcookie/3 where domain or path options derive from untrusted request data.
- Inspect outbound HTTP responses for malformed or duplicated Set-Cookie headers using a reverse proxy or response-inspection middleware.
Monitoring Recommendations
- Log and alert on inbound Host headers or request paths containing control bytes or semicolons before they reach application logic.
- Monitor response headers for Set-Cookie entries whose Domain or Path values include whitespace, semicolons, or non-printable characters.
- Correlate response-splitting indicators with cache poisoning patterns at upstream CDN or proxy layers.
How to Mitigate CVE-2026-47069
Immediate Actions Required
- Upgrade hackney to version 4.0.1 or later in all Erlang and Elixir applications that include it directly or transitively.
- Audit application code paths that pass request-derived values into hackney cookie domain or path options and add input validation upstream.
- Reject or sanitize inbound Host headers and request paths containing CR, LF, NUL, or semicolon bytes at the ingress layer.
Patch Information
The fix is committed in 8e02b99c28aea1b3fa2ddc0e66f51fe5bb0ac540 and shipped in hackney 4.0.1. Details are published in GitHub Security Advisory GHSA-mp55-p8c9-rfw2, the CNA CVE-2026-47069 Record, and the OSV Vulnerability Report EEF-CVE-2026-47069.
Workarounds
- Validate domain and path option values for CRLF, NUL, whitespace, and ; before invoking hackney cookie functions if immediate upgrade is not possible.
- Strip or reject CRLF sequences from request-derived inputs at the reverse proxy or WAF tier.
- Avoid forwarding the raw inbound Host header or request path into outbound cookie attributes; use a validated allowlist of domains and paths instead.
# Update hackney in a rebar3 project
rebar3 upgrade hackney
# Or pin the fixed version in rebar.config
# {deps, [{hackney, "4.0.1"}]}.
# For Elixir projects using Mix
mix deps.update hackney
# Or pin in mix.exs: {:hackney, "~> 4.0.1"}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


