CVE-2026-54892: Plug: quadratic-time decoding of nested query/body parameters enables denial of service

Published Jun 23, 2026
·
Updated

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.splitkeys/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.insertkeys/3 then does one Map.put per level keyed on that growing prefix, hashing the full byte range each time, and Plug.Conn.Query.finalizepointer/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 decodeeach/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

Other sources

Inefficient algorithmic complexity in Plug's nested-parameter decoder allows an unauthenticated remote attacker to cause denial of service. Plug.Conn.Query.decode/4 (and Plug.Conn.Query.decodeeach/2) parse query strings and application/x-www-form-urlencoded request bodies. When a key contains many bracketed segments such as a[a][a][a]=1, the decoder walks the brackets and, for each of the N levels, performs a map operation keyed on an ever-growing binary prefix of the key, hashing the full byte range at each step. The total decode cost is therefore quadratic in the number of nesting levels.

With the default Plug.Parsers.URLENCODED body limit of 1,000,000 bytes, a single request can carry roughly 333,000 nesting levels and saturate a BEAM scheduler for minutes. A small number of concurrent requests can saturate all schedulers and render a Plug-based server unresponsive. No authentication or knowledge of application routes is required.

This vulnerability is associated with program files lib/plug/conn/query.ex and program routines Plug.Conn.Query.decode/4, Plug.Conn.Query.decodeeach/2, Plug.Conn.Query.splitkeys/6, Plug.Conn.Query.insertkeys/3, and Plug.Conn.Query.finalizepointer/2.

This issue affects plug from 1.15.0 before 1.15.5, 1.16.4, 1.17.2, 1.18.3, and 1.19.3.

— NVD

Affected Software

6 affected componentsFixes available
hex/plug>=1.15.0<1.15.5, =1.16.4, =1.17.2, =1.18.3, =1.19.3
erlang/plug>=1.19.0<1.19.3
1.19.3
erlang/plug>=1.18.0<1.18.3
1.18.3
erlang/plug>=1.17.0<1.17.2
1.17.2
erlang/plug>=1.16.0<1.16.4
1.16.4
erlang/plug>=1.15.0<1.15.5
1.15.5

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade erlang/plug to a version that resolves this vulnerability.

    Fixed in 1.19.3
  2. Upgrade

    Upgrade erlang/plug to a version that resolves this vulnerability.

    Fixed in 1.18.3
  3. Upgrade

    Upgrade erlang/plug to a version that resolves this vulnerability.

    Fixed in 1.17.2
  4. Upgrade

    Upgrade erlang/plug to a version that resolves this vulnerability.

    Fixed in 1.16.4
  5. Upgrade

    Upgrade erlang/plug to a version that resolves this vulnerability.

    Fixed in 1.15.5
  6. Upgrade

    Upgrade Plug to a version that resolves this vulnerability.

    Fixed in 1.15.5
  7. Upgrade

    Upgrade Plug to a version that resolves this vulnerability.

    Fixed in 1.16.4
  8. Upgrade

    Upgrade Plug to a version that resolves this vulnerability.

    Fixed in 1.17.2
  9. Upgrade

    Upgrade Plug to a version that resolves this vulnerability.

    Fixed in 1.18.3
  10. Upgrade

    Upgrade Plug to a version that resolves this vulnerability.

    Fixed in 1.19.3

Event History

Jun 23, 2026
CVE Published
via MITRE·12:31 PM
Data Sourced
via MITRE·12:31 PM
DescriptionWeakness
Data Sourced
via NVD·01:16 PM
DescriptionSeverityWeakness
Sep 23, 2026
Advisory Published
via GitHub·02:00 PM
Data Sourced
via GitHub·02:00 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-54892?

CVE-2026-54892 has a risk rating of 66, indicating a significant potential for denial of service.

2

How do I fix CVE-2026-54892?

To mitigate CVE-2026-54892, ensure you are using the latest version of the Plug library that includes the fix for this vulnerability.

3

What is the impact of CVE-2026-54892?

CVE-2026-54892 allows an unauthenticated remote attacker to exploit the inefficient decoding algorithm, resulting in potential denial of service.

4

Who is affected by CVE-2026-54892?

CVE-2026-54892 affects applications using the Plug library that process nested query and body parameters.

5

What conditions are required to exploit CVE-2026-54892?

An attacker needs to send crafted query strings or application/x-www-form-urlencoded request bodies containing numerous keys to exploit CVE-2026-54892.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203