Answer in brief
CVE-2026-54892 records a High severity (CVSS 8.7) vulnerability in Plug: quadratic-time decoding of nested query/body parameters enables denial of service. The current sources do not mark it as known exploited. The current feed maps plug (erlang), plug (erlang), plug (erlang), plug (erlang) and additional mapped packages. Check affected ranges and fixed versions before updating.
Analysis pending evidence review
HOL Guard separates source facts from reviewed analysis. See the methodology.
CVSS is 8.7. The current sources do not mark it as known exploited. Treat this as a source-backed prioritization signal, not a statement about your environment.
Analysis status
Analysis pending evidence review
Factual feed record only; HOL analysis is not approved for indexing. Read the methodology.
The current feed maps plug (erlang), plug (erlang), plug (erlang), plug (erlang) and additional mapped packages. Check affected ranges and fixed versions before updating.
| Package | Affected range | Fixed version |
|---|---|---|
| plugerlang | >=1.15.0,<1.15.5 | 1.15.5 |
| plugerlang | >=1.16.0,<1.16.4 | 1.16.4 |
| plugerlang | >=1.17.0,<1.17.2 | 1.17.2 |
| plugerlang | >=1.18.0,<1.18.3 | 1.18.3 |
| plugerlang | >=1.19.0,<1.19.3 | 1.19.3 |
Published upstream
Jun 23, 2026
Evidence: source:ghsa:source_dates:source-dates:recordSource modified
Sep 23, 2026
Evidence: source:ghsa:source_dates:source-dates:recordFirst seen by HOL
Jun 23, 2026
### Summary Plug's nested-parameter decoder (`Plug.Conn.Query`) parses URL-encoded keys in time quadratic in their bracket-nesting depth. Any unauthenticated remote attacker that can reach a Plug-based HTTP endpoint can pin a BEAM scheduler for minutes with a single small request. ### Details For a key like `a[a][a]...=1`, `Plug.Conn.Query.split_keys/6` (in `lib/plug/conn/query.ex`) builds an accumulator of `:binary.part` prefixes (`a`, `a[a]`, `a[a][a]`, …) that grow ~3 bytes per level. `Plug.Conn.Query.insert_keys/3` then does one `Map.put` per level keyed on that growing prefix, hashing the full byte range each time, and `Plug.Conn.Query.finalize_pointer/2` repeats the prefix-keyed walk to materialize the structure. Total cost is `O(N²)` in nesting depth. The same code path handles query strings, `application/x-www-form-urlencoded` bodies, and multipart field names via `Plug.Conn.Query.decode/4` and `decode_each/2`. The default `Plug.Parsers.URLENCODED` cap is 1 MB (~333,000 nesting levels), but `Plug.Parsers` accepts urlencoded payloads up to its overall body limit (20 MB by default), so an attacker can scale the per-request work well beyond the urlencoded-specific cap. The decoder shows ~4× scaling per 2× input (16k levels ≈ 195 ms on a single scheduler). ### PoC 1. POST `a[a][a]...[a]=1` as `application/x-www-form-urlencoded` to any endpoint of a Plug-based app. Even at the 1 MB urlencoded-parser default the payload carries ~333,000 nesting levels; with the broader `Plug.Parsers` body limit (20 MB default) a single request can carry millions. 2. Launch one such request per scheduler concurrently. Each pins a scheduler for minutes; legitimate traffic stalls once all schedulers are busy. ### Impact A single low-bandwidth sender can render any internet-reachable Plug-based service (most Phoenix and standalone Elixir/Erlang web stacks) unresponsive. No credentials, specific endpoint, or prior knowledge of the application is required. ### References * Introduction commit: https://github.com/elixir-plug/plug/commit/712b875d3442c765d8d37e546ffd5ad9f8afcc55 * Patch commit: https://github.com/elixir-plug/plug/commit/b4aa8a0665ce2726a6d5af44467fb4f59595b107
Quoted source text, attributed separately from HOL analysis.