Skip to content

CVE-2026-39804 - Bandit permessage-deflate decompression DoS

Bandit 0.5.9 through 1.10.4 can exhaust BEAM memory while inflating a compressed WebSocket message. When WebSocket permessage-deflate is negotiated, Bandit’s inflate path can materialize the decompressed payload without enforcing an output-size cap. A small compressed frame can therefore expand into a much larger allocation before application code runs.

This issue is reachable only when both Bandit’s server-level WebSocket compression support is enabled and an application passes compress: true to WebSockAdapter.upgrade/4. Stock Phoenix and LiveView defaults are less exposed because their per-upgrade compression option defaults to false, but repositories should still check custom socket upgrades and endpoint configuration.

Affected versions

  • Vulnerable: Hex package bandit >=0.5.9, <1.11.0
  • Fixed: bandit 1.11.0+

Indicator-of-exposure

  • The repository builds or deploys an Elixir/Phoenix application that depends on Hex package bandit.
  • mix.lock, mix.exs, an image SBOM, release metadata, or deployment artifact resolves bandit to >=0.5.9, <1.11.0.
  • The service accepts WebSocket upgrades through Bandit.
  • WebSockAdapter.upgrade/4 or a wrapper passes compress: true, and the server-level WebSocket compression option is enabled.
  • Public, partner, tenant, or otherwise untrusted clients can open compressed WebSocket connections to the service.

Quick checks:

rg -n "bandit|Bandit|websocket_options|compress:\\s*true|WebSockAdapter\\.upgrade|permessage|deflate|socket|LiveView" .
mix deps | rg '^\\* bandit '
mix hex.outdated bandit
mix phx.routes | rg -i "socket|live"

Remediation strategy

  • Upgrade every controlled Bandit runtime to 1.11.0+.
  • Regenerate mix.lock, release metadata, container images, SBOMs, and rendered deployment artifacts that pin or report dependency versions.
  • If the upgrade is blocked, remove compress: true from affected WebSockAdapter.upgrade/4 calls or otherwise disable permessage-deflate negotiation until patched.
  • For internet-facing WebSocket services, add short-term monitoring for memory pressure, connection spikes, and unexpected node restarts during rollout.
  • Check CVE-2026-42786 in the same change because it affects broader Bandit WebSocket handling and has the same fixed version.

The prompt

Model context: this prompt was generated by GPT 5.5 Extra High reasoning.

You are remediating CVE-2026-39804 (Bandit WebSocket permessage-deflate
decompression denial of service). Produce exactly one output:

- A reviewer-ready PR/change request that upgrades Bandit, verifies compressed
  WebSocket exposure, adds safe dependency/deployment validation, and documents
  operator containment, or
- TRIAGE.md if this repository does not own an affected Bandit runtime or safe
  patch path.

## Rules

- Scope only CVE-2026-39804.
- Do not generate, run, or commit decompression bombs or denial-of-service
  payloads.
- Do not run memory-exhaustion tests against production, staging, preview, or
  shared services.
- Do not disable WebSocket compression permanently without explaining behavior
  and performance impact.
- Do not auto-merge.

## Steps

1. Inventory Bandit usage controlled by this repository: `mix.exs`,
   `mix.lock`, umbrella apps, releases, Dockerfiles, base images, SBOMs, Helm
   values, Kubernetes manifests, Terraform, compose files, deployment scripts,
   and generated dependency reports.
2. Determine every resolved Hex package `bandit` version. A runtime is
   vulnerable if it resolves to `>=0.5.9, <1.11.0`.
3. Identify compressed WebSocket exposure:
   - `WebSockAdapter.upgrade/4`;
   - `compress: true`;
   - wrappers around WebSock upgrades;
   - Bandit `websocket_options` compression configuration;
   - Phoenix Channels or LiveView customizations that enable compression;
   - ingress, CDN, load balancer, or route rules that expose those endpoints to
     untrusted clients.
4. If this repository only contains clients, documentation, or deployment
   pointers to an externally owned service, stop with `TRIAGE.md` naming the
   owner, evidence checked, and required fixed version `bandit 1.11.0+`.
5. Upgrade vulnerable Bandit runtimes to `1.11.0+` on the smallest compatible
   release line. Regenerate `mix.lock`, release artifacts, dependency reports,
   SBOMs, image digests, and rendered deployment manifests as appropriate for
   this repository.
6. If dependency constraints prevent the upgrade, update the direct dependency
   that pins Bandit, add the narrowest override supported by the build, or stop
   with `TRIAGE.md` explaining the blocker and temporary containment.
7. If immediate upgrade is blocked and this repository controls the WebSocket
   upgrade code, remove or feature-flag `compress: true` for affected
   `WebSockAdapter.upgrade/4` paths. Keep the change reversible and document
   that it is containment until Bandit is upgraded.
8. Add a safe regression or policy check that proves the resolved Bandit version
   is not vulnerable. Good examples:
   - a lockfile/dependency assertion for `bandit >=1.11.0`;
   - a release metadata check;
   - a deployment-render test that confirms the patched image or release is
     used;
   - a configuration test that proves emergency compression disablement renders
     when that knob exists.
   Avoid tests that intentionally inflate large compressed payloads.
9. Add a PR body section named `CVE-2026-39804 operator actions` that states:
   - resolved Bandit versions before and after the change;
   - whether any WebSocket upgrade path sets `compress: true`;
   - whether server-level WebSocket compression is enabled;
   - which endpoints are reachable by untrusted clients;
   - what containment is required before or during rollout;
   - whether memory-pressure or restart telemetry should be reviewed;
   - whether CVE-2026-42786 also applies to this deployment.
10. Run available validation: `mix deps.get`, `mix deps.unlock --check-unused`
    if used locally, `mix compile --warnings-as-errors` when appropriate,
    tests, format, dependency/security scans, image build, release build, and
    deployment rendering.
11. Use PR title:
    `fix(sec): remediate CVE-2026-39804 in Bandit`.

## Stop conditions

- No affected Bandit runtime is controlled by this repository.
- The resolved Bandit version is already `1.11.0+` across lockfiles, release
  metadata, SBOMs, and images.
- No WebSocket path is exposed and the repository cannot validate the runtime
  owner's deployment.
- A fixed Bandit release cannot be consumed without a larger Phoenix, Plug, or
  Elixir migration.
- Verifying exposure would require running decompression bombs or
  memory-exhaustion tests.
- The only apparent mitigation would silently break public WebSocket behavior
  without operator approval.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No deployable Elixir release, image, lockfile, SBOM, or generated dependency report resolves bandit below 1.11.0.
  • Compressed WebSocket exposure is explicitly inventoried, including compress: true and server-level compression configuration.
  • Tests or policy checks prove the patched dependency is resolved without using unsafe decompression payloads.
  • Any temporary compression-disablement or ingress containment is clearly labeled as temporary and reversible.
  • The PR calls out whether the related Bandit fragment reassembly advisory CVE-2026-42786 is also relevant.

Watch for

  • Custom WebSock upgrade wrappers where compress: true is hidden behind a helper or endpoint macro.
  • Assuming Phoenix or LiveView defaults prove safety without checking local overrides.
  • Container images that still carry an older release after mix.lock was fixed.
  • Treating WebSocket compression disablement as a complete fix instead of a temporary control.
  • Confusing the Elixir bandit server with the unrelated Python security scanner named Bandit.

References