---
id: "CVE-2026-108529"
kind: "vulnerability"
aliases: ["CVE-2026-108529"]
title: "Bandit: HTTP/2 frames let remote clients exhaust server CPU"
severity: "high"
cvss: 8.7
epss: null
exploited: false
status: "open"
category: "package"
products: []
ecosystems: []
tags: ["bandit", "elixir", "http2", "package", "phoenix", "self-hosted"]
not_affected_if: ["bandit-1.14-or-later", "http1-only"]
published_at: "2026-10-26T14:16:24+00:00"
first_seen_at: "2026-10-26T14:30:36+00:00"
updated_at: "2026-10-26T14:32:16+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-108529", "first_seen_at": "2026-10-26T14:30:36+00:00"}]
---

# Bandit: HTTP/2 frames let remote clients exhaust server CPU

Bandit, an Elixir HTTP server, has an HTTP/2 flaw where a few cheap frames make it reprocess a large queue of blocked responses. An unauthenticated remote attacker can open many streams and send small SETTINGS or WINDOW_UPDATE frames to exhaust server CPU.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- Check the Bandit version in `mix.lock` or `mix deps` output; affected versions are `0.3.4` up to but not including `1.14.0`
- Confirm HTTP/2 is served by Bandit (for example via Phoenix endpoints with HTTP/2 enabled)

## Fix

- Upgrade `bandit` to `1.14.0` or later with `mix deps.update bandit`

## Timeline

- 2026-10-26T14:30:36+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-108529

## From the sources

Inefficient Algorithmic Complexity vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server CPU via small SETTINGS or connection-level WINDOW_UPDATE frames. The attacker opens thousands of streams whose responses block on the connection send window, then sends cheap frames that each make the server walk the whole queue of blocked sends. In the reporter's run, with 3,000 blocked streams a single 9-byte SETTINGS frame took 133 ms to process.

do_pending_sends/2 in lib/bandit/http2/connection.ex retries every queued send and, before each retry, removes that entry from the queue with List.delete/2, so one frame costs O(n²) list operations for n blocked streams. max_concurrent_streams defaults to :infinity, so the attacker chooses n.

This issue affects bandit: from 0.3.4 before 1.14.0.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
