CVE-2026-47077: Hackney Per-chunk Timeout With Unbounded Body Vulnerability

HIGH
Advisory Identifier: GHSA-jq4m-q6p2-8gwc
CWE-400 CWE-295
Published
Advisory Summary

CVE-2026-47077 is a HIGH per-chunk timeout with unbounded body vulnerability (CWE-400: Uncontrolled Resource Consumption) affecting Hackney libraries in the Hex ecosystem. The issue involves per-chunk timeout with unbounded body accumulation enables slow-drip oom. Remediation is available by upgrading affected packages to version 4.0.1.

CVE-2026-47077 at a Glance

CVE Identifier CVE-2026-47077
GHSA Identifier GHSA-jq4m-q6p2-8gwc
Severity HIGH
CVSS v3.1 Base Score N/A
CWE Classification CWE-400: Uncontrolled Resource Consumption
Affected Product Hackney
Package Ecosystem Hex
Published Date
Last Updated

How to Fix CVE-2026-47077

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.

hackney fixed: 4.0.1
Upgrade hackney to 4.0.1
Verify Direct and Transitive Dependencies

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-47077, 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-400: Uncontrolled Resource Consumption, where the product does not properly control the allocation and maintenance of a limited resource. 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

### Summary `hackney_h3:await_response_loop/6` in `src/hackney_h3.erl` accumulates the HTTP/3 response body in memory without any size cap. The `after Timeout` clause is a per-message inactivity timer, not a wall-clock deadline: every received `stream_data` chunk, housekeeping `select` message, or `settings` frame resets it. A malicious HTTP/3 server that drips one small chunk every `Timeout - 1` ms with `Fin = false` and never terminates the stream keeps the loop alive indefinitely while the accumulation buffer grows without bound, eventually exhausting the BEAM process heap. ### Details In `src/hackney_h3.erl`, `await_response_loop/6` (line 430) builds the body with: ```erlang NewBody = <<AccBody/binary, Data/binary>> ``` There is no `max_body` check and no monotonic deadline. The `after Timeout` clause at line 463 is restarted on each loop iteration. A server that ensures at least one message arrives within `Timeout` ms indefinitely (one small chunk per interval is sufficient) prevents the timeout from firing while `AccBody` grows linearly. The same module's `wait_connected/3` (lines 388-389) shows the correct pattern: track an absolute start time and pass a shrinking `Remaining` budget into each `receive`. This loop does not. ### Configurations Only the HTTP/3 transport is affected. Applications using the default TCP/TLS hackney transport are not vulnerable. The vulnerability requires using `hackney_h3` directly or passing `{transport, h3}` to `hackney:request/5`. ### PoC 1. Stand up an HTTP/3 server that responds with `200 OK` headers (`Fin = false`), then emits a small `stream_data` chunk every `Timeout - margin` ms with `Fin = false` indefinitely. 2. Issue `hackney:request(get, Url, [], <<>>, [{transport, h3}])` against it. 3. Watch the client process heap grow monotonically. The configured timeout never fires; the process is eventually killed by `max_heap_size` or the OS OOM killer. ### Impact Remote denial of service via unbounded memory consumption. Affects hackney 2.0.0 through 4.0.0 when using the HTTP/3 transport against an attacker-controlled or attacker-influenced server. Each affected request consumes unbounded memory until the BEAM is killed. CVSS v4.0: **8.2 (HIGH)**. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/0334af206d5099fdf510ed9eda18e34396f065ad * Patch commit: https://github.com/benoitc/hackney/commit/3d25f9fea26c90609de9d64366fedfe5065413bc

CVE-2026-47077 Affected Hackney Versions

1 component(s)
Fixed Versions:
4.0.1
Product / Package Ecosystem Affected Versions Fixed Version
hackney
Hex
≥ 2.0.0
< 4.0.1
4.0.1

References

Frequently Asked Questions

What is CVE-2026-47077?
CVE-2026-47077 is a security vulnerability in Hackney involving Per-chunk timeout with unbounded body accumulation enables slow-drip OOM under CWE-400: Uncontrolled Resource Consumption.
Which Hackney versions are affected?
Affected versions include releases prior to 4.0.1 across affected packages: hackney.
What version fixes CVE-2026-47077?
Upgrading to 4.0.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is hackney affected?
Yes, hackney is affected in releases prior to 4.0.1. Upgrade your dependency to 4.0.1 or later.
What CWE is associated with CVE-2026-47077?
CVE-2026-47077 is classified under CWE-400: Uncontrolled Resource Consumption (The product does not properly control the allocation and maintenance of a limited resource.).
How can I check Hex dependencies for CVE-2026-47077?
Run the dependency tree command: 'inspect dependencies for hackney'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-jq4m-q6p2-8gwc",
  "modified" : "2026-06-30T17:16:10Z",
  "published" : "2026-06-26T21:57:33Z",
  "aliases" : [ "CVE-2026-47077" ],
  "summary" : "Hackney: Per-chunk timeout with unbounded body accumulation enables slow-drip OOM",
  "details" : "### Summary\n\n`hackney_h3:await_response_loop/6` in `src/hackney_h3.erl` accumulates the HTTP/3 response body in memory without any size cap. The `after Timeout` clause is a per-message inactivity timer, not a wall-clock deadline: every received `stream_data` chunk, housekeeping `select` message, or `settings` frame resets it. A malicious HTTP/3 server that drips one small chunk every `Timeout - 1` ms with `Fin = false` and never terminates the stream keeps the loop alive indefinitely while the accumulation buffer grows without bound, eventually exhausting the BEAM process heap.\n\n### Details\n\nIn `src/hackney_h3.erl`, `await_response_loop/6` (line 430) builds the body with:\n\n```erlang\nNewBody = <<AccBody/binary, Data/binary>>\n```\n\nThere is no `max_body` check and no monotonic deadline. The `after Timeout` clause at line 463 is restarted on each loop iteration. A server that ensures at least one message arrives within `Timeout` ms indefinitely (one small chunk per interval is sufficient) prevents the timeout from firing while `AccBody` grows linearly. The same module's `wait_connected/3` (lines 388-389) shows the correct pattern: track an absolute start time and pass a shrinking `Remaining` budget into each `receive`. This loop does not.\n\n### Configurations\n\nOnly the HTTP/3 transport is affected. Applications using the default TCP/TLS hackney transport are not vulnerable. The vulnerability requires using `hackney_h3` directly or passing `{transport, h3}` to `hackney:request/5`.\n\n### PoC\n\n1. Stand up an HTTP/3 server that responds with `200 OK` headers (`Fin = false`), then emits a small `stream_data` chunk every `Timeout - margin` ms with `Fin = false` indefinitely.\n2. Issue `hackney:request(get, Url, [], <<>>, [{transport, h3}])` against it.\n3. Watch the client process heap grow monotonically. The configured timeout never fires; the process is eventually killed by `max_heap_size` or the OS OOM killer.\n\n### Impact\n\nRemote denial of service via unbounded memory consumption. Affects hackney 2.0.0 through 4.0.0 when using the HTTP/3 transport against an attacker-controlled or attacker-influenced server. Each affected request consumes unbounded memory until the BEAM is killed. CVSS v4.0: **8.2 (HIGH)**.\n\n## Resources\n\n* Introduction commit: https://github.com/benoitc/hackney/commit/0334af206d5099fdf510ed9eda18e34396f065ad\n* Patch commit: https://github.com/benoitc/hackney/commit/3d25f9fea26c90609de9d64366fedfe5065413bc",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Hex",
      "name" : "hackney"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "4.0.1"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/benoitc/hackney/security/advisories/GHSA-jq4m-q6p2-8gwc"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ex-aws/ex_aws_sns/security/advisories/GHSA-8jgf-23q5-x7xx"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-47077"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/benoitc/hackney/commit/3d25f9fea26c90609de9d64366fedfe5065413bc"
  }, {
    "type" : "WEB",
    "url" : "https://cna.erlef.org/cves/CVE-2026-47077.html"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/benoitc/hackney"
  }, {
    "type" : "WEB",
    "url" : "https://osv.dev/vulnerability/EEF-CVE-2026-47077"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-295", "CWE-400" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-26T21:57:33Z",
    "nvd_published_at" : "2026-05-28T10:16:39Z"
  }
}