Refine your search

5 vulnerabilities found for plug by elixir-plug

CVE-2026-105963 (GCVE-0-2026-105963)
Vulnerability from cvelistv5
Published
2026-10-23 09:56
Modified
2026-10-23 13:39
CWE
  • CWE-532 - Insertion of Sensitive Information into Log File
Summary
Externally-Generated Error Message Containing Sensitive Information vulnerability in plug_crypto in elixir-plug plug_crypto allows an unauthenticated remote attacker to expose the secret key base through application logs via a wrong-typed argument. Every public function in Plug.Crypto validates argument types in a function-head guard. A failed guard makes the Erlang VM raise FunctionClauseError with the actual argument values in the top stack frame, so the secret key base, a derived key, or the value an API key is compared against lands in that frame. The library's rescue blocks and Plug.Crypto.prune_args_from_stacktrace/1 only reach exceptions raised inside a function body, so they never see a guard failure. Plug.Cowboy and Bandit write the frame to the error log and attach it as crash_reason Logger metadata, which error trackers forward. Two entry points take request data. Plug.Crypto.verify/4 exposes the secret key base when the token is neither a binary nor nil, which Phoenix.Token.verify/4 reaches because it forwards the token unguarded. Plug.Crypto.secure_compare/2 exposes the other operand when one side is not a binary, as happens when a missing request header yields nil. Reading the leaked value needs separate access to the logs or the error tracker, so the request alone does not disclose the secret to the attacker. This issue affects plug: from 1.6.3 before 1.7.0; plug_crypto: from 1.0.0 before 2.2.1.
Impacted products
Vendor Product Version
elixir-plug plug Version: 1.6.3   ≤
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug Version: 56000c33d8a0a2fbac491f8be06b9c5112bc2276
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug_crypto Version: 1.0.0   ≤
    cpe:2.3:a:elixir-plug:plug_crypto:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug_crypto Version: 2d078b7b8264c565f0ff71235c515f4f46882dcf
    cpe:2.3:a:elixir-plug:plug_crypto:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-105963",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-10-23T10:53:00.474296Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-10-23T13:39:29.887Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Crypto\u0027"
          ],
          "packageName": "plug",
          "packageURL": "pkg:hex/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/crypto.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:secure_compare/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:masked_compare/3"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "1.7.0",
              "status": "affected",
              "version": "1.6.3",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Crypto\u0027"
          ],
          "packageName": "elixir-plug/plug",
          "packageURL": "pkg:github/elixir-plug/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/crypto.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:secure_compare/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:masked_compare/3"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "*",
              "status": "affected",
              "version": "56000c33d8a0a2fbac491f8be06b9c5112bc2276",
              "versionType": "git"
            }
          ]
        },
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug_crypto:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Crypto\u0027",
            "\u0027Elixir.Plug.Crypto.MessageVerifier\u0027",
            "\u0027Elixir.Plug.Crypto.MessageEncryptor\u0027"
          ],
          "packageName": "plug_crypto",
          "packageURL": "pkg:hex/plug_crypto",
          "product": "plug_crypto",
          "programFiles": [
            "lib/plug/crypto.ex",
            "lib/plug/crypto/message_verifier.ex",
            "lib/plug/crypto/message_encryptor.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:verify/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:decrypt/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:secure_compare/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:masked_compare/3"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:mask/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:sign/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:encrypt/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageVerifier\u0027:sign/3"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageVerifier\u0027:verify/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageEncryptor\u0027:encrypt/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageEncryptor\u0027:decrypt/4"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug_crypto",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "2.2.1",
              "status": "affected",
              "version": "1.0.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug_crypto:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Crypto\u0027",
            "\u0027Elixir.Plug.Crypto.MessageVerifier\u0027",
            "\u0027Elixir.Plug.Crypto.MessageEncryptor\u0027"
          ],
          "packageName": "elixir-plug/plug_crypto",
          "packageURL": "pkg:github/elixir-plug/plug_crypto",
          "product": "plug_crypto",
          "programFiles": [
            "lib/plug/crypto.ex",
            "lib/plug/crypto/message_verifier.ex",
            "lib/plug/crypto/message_encryptor.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:verify/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:decrypt/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:secure_compare/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:masked_compare/3"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:mask/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:sign/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto\u0027:encrypt/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageVerifier\u0027:sign/3"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageVerifier\u0027:verify/2"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageEncryptor\u0027:encrypt/4"
            },
            {
              "name": "\u0027Elixir.Plug.Crypto.MessageEncryptor\u0027:decrypt/4"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug_crypto",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "981887493dada0fce7003c61861c00dfbb0fc8c5",
              "status": "affected",
              "version": "2d078b7b8264c565f0ff71235c515f4f46882dcf",
              "versionType": "git"
            }
          ]
        }
      ],
      "configurations": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eRequest-data reachability needs an application that passes unvalidated request data into \u003ccode\u003ePlug.Crypto\u003c/code\u003e. Either a controller or plug that hands \u003ccode\u003eparams[\"token\"]\u003c/code\u003e to \u003ccode\u003ePhoenix.Token.verify/4\u003c/code\u003e or \u003ccode\u003ePhoenix.Token.decrypt/4\u003c/code\u003e, where \u003ccode\u003ePlug.Parsers\u003c/code\u003e yields a list for \u003ccode\u003etoken[]=x\u003c/code\u003e in a query string and an integer or a map for a JSON body, or a call to \u003ccode\u003ePlug.Crypto.secure_compare/2\u003c/code\u003e on a value that can be nil, such as \u003ccode\u003eList.first(get_req_header(conn, \"x-api-key\"))\u003c/code\u003e compared against a configured secret. Disclosure of the leaked value additionally needs read access to the application logs or to an error tracker that receives \u003ccode\u003ecrash_reason\u003c/code\u003e metadata. The remaining affected functions require direct misuse by application code and have no request-data trigger.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Request-data reachability needs an application that passes unvalidated request data into `Plug.Crypto`. Either a controller or plug that hands `params[\"token\"]` to `Phoenix.Token.verify/4` or `Phoenix.Token.decrypt/4`, where `Plug.Parsers` yields a list for `token[]=x` in a query string and an integer or a map for a JSON body, or a call to `Plug.Crypto.secure_compare/2` on a value that can be nil, such as `List.first(get_req_header(conn, \"x-api-key\"))` compared against a configured secret. Disclosure of the leaked value additionally needs read access to the application logs or to an error tracker that receives `crash_reason` metadata. The remaining affected functions require direct misuse by application code and have no request-data trigger."
            }
          ],
          "value": "Request-data reachability needs an application that passes unvalidated request data into Plug.Crypto. Either a controller or plug that hands params[\"token\"] to Phoenix.Token.verify/4 or Phoenix.Token.decrypt/4, where Plug.Parsers yields a list for token[]=x in a query string and an integer or a map for a JSON body, or a call to Plug.Crypto.secure_compare/2 on a value that can be nil, such as List.first(get_req_header(conn, \"x-api-key\")) compared against a configured secret. Disclosure of the leaked value additionally needs read access to the application logs or to an error tracker that receives crash_reason metadata. The remaining affected functions require direct misuse by application code and have no request-data trigger."
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.7.0",
                  "versionStartIncluding": "1.6.3",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug_crypto:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "2.2.1",
                  "versionStartIncluding": "1.0.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "reporter",
          "value": "Neil Berkman"
        },
        {
          "lang": "en",
          "type": "finder",
          "value": "Neil Berkman"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Neil Berkman"
        },
        {
          "lang": "en",
          "type": "coordinator",
          "value": "Jonatan M\u00e4nnchen / EEF"
        },
        {
          "lang": "en",
          "type": "remediation verifier",
          "value": "Jos\u00e9 Valim"
        }
      ],
      "dateAssigned": "2026-10-22T09:25:19.000Z",
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eExternally-Generated Error Message Containing Sensitive Information vulnerability in \u003ccode\u003eplug_crypto\u003c/code\u003e in elixir-plug plug_crypto allows an unauthenticated remote attacker to expose the secret key base through application logs via a wrong-typed argument. Every public function in \u003ccode\u003ePlug.Crypto\u003c/code\u003e validates argument types in a function-head guard. A failed guard makes the Erlang VM raise \u003ccode\u003eFunctionClauseError\u003c/code\u003e with the actual argument values in the top stack frame, so the secret key base, a derived key, or the value an API key is compared against lands in that frame. The library\u0027s \u003ccode\u003erescue\u003c/code\u003e blocks and \u003ccode\u003ePlug.Crypto.prune_args_from_stacktrace/1\u003c/code\u003e only reach exceptions raised inside a function body, so they never see a guard failure. Plug.Cowboy and Bandit write the frame to the error log and attach it as \u003ccode\u003ecrash_reason\u003c/code\u003e Logger metadata, which error trackers forward.\u003c/p\u003e\n\u003cp\u003eTwo entry points take request data. \u003ccode\u003ePlug.Crypto.verify/4\u003c/code\u003e exposes the secret key base when the token is neither a binary nor nil, which \u003ccode\u003ePhoenix.Token.verify/4\u003c/code\u003e reaches because it forwards the token unguarded. \u003ccode\u003ePlug.Crypto.secure_compare/2\u003c/code\u003e exposes the other operand when one side is not a binary, as happens when a missing request header yields nil. Reading the leaked value needs separate access to the logs or the error tracker, so the request alone does not disclose the secret to the attacker.\u003c/p\u003e\n\u003cp\u003eThis issue affects plug: from 1.6.3 before 1.7.0; plug_crypto: from 1.0.0 before 2.2.1.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Externally-Generated Error Message Containing Sensitive Information vulnerability in `plug_crypto` in elixir-plug plug_crypto allows an unauthenticated remote attacker to expose the secret key base through application logs via a wrong-typed argument. Every public function in `Plug.Crypto` validates argument types in a function-head guard. A failed guard makes the Erlang VM raise `FunctionClauseError` with the actual argument values in the top stack frame, so the secret key base, a derived key, or the value an API key is compared against lands in that frame. The library\u0027s `rescue` blocks and `Plug.Crypto.prune_args_from_stacktrace/1` only reach exceptions raised inside a function body, so they never see a guard failure. Plug.Cowboy and Bandit write the frame to the error log and attach it as `crash_reason` Logger metadata, which error trackers forward.\n\nTwo entry points take request data. `Plug.Crypto.verify/4` exposes the secret key base when the token is neither a binary nor nil, which `Phoenix.Token.verify/4` reaches because it forwards the token unguarded. `Plug.Crypto.secure_compare/2` exposes the other operand when one side is not a binary, as happens when a missing request header yields nil. Reading the leaked value needs separate access to the logs or the error tracker, so the request alone does not disclose the secret to the attacker.\n\nThis issue affects plug: from 1.6.3 before 1.7.0; plug_crypto: from 1.0.0 before 2.2.1."
            }
          ],
          "value": "Externally-Generated Error Message Containing Sensitive Information vulnerability in plug_crypto in elixir-plug plug_crypto allows an unauthenticated remote attacker to expose the secret key base through application logs via a wrong-typed argument. Every public function in Plug.Crypto validates argument types in a function-head guard. A failed guard makes the Erlang VM raise FunctionClauseError with the actual argument values in the top stack frame, so the secret key base, a derived key, or the value an API key is compared against lands in that frame. The library\u0027s rescue blocks and Plug.Crypto.prune_args_from_stacktrace/1 only reach exceptions raised inside a function body, so they never see a guard failure. Plug.Cowboy and Bandit write the frame to the error log and attach it as crash_reason Logger metadata, which error trackers forward.\n\nTwo entry points take request data. Plug.Crypto.verify/4 exposes the secret key base when the token is neither a binary nor nil, which Phoenix.Token.verify/4 reaches because it forwards the token unguarded. Plug.Crypto.secure_compare/2 exposes the other operand when one side is not a binary, as happens when a missing request header yields nil. Reading the leaked value needs separate access to the logs or the error tracker, so the request alone does not disclose the secret to the attacker.\n\nThis issue affects plug: from 1.6.3 before 1.7.0; plug_crypto: from 1.0.0 before 2.2.1."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-54",
          "descriptions": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eAn unauthenticated attacker sends one request with a wrong-typed parameter, or omits a header, and the secret key base or the compared secret is written into the application log and into \u003ccode\u003ecrash_reason\u003c/code\u003e metadata forwarded to error trackers. Anyone who can read those logs then holds a key sufficient to mint session cookies and tokens under any salt.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "An unauthenticated attacker sends one request with a wrong-typed parameter, or omits a header, and the secret key base or the compared secret is written into the application log and into `crash_reason` metadata forwarded to error trackers. Anyone who can read those logs then holds a key sufficient to mint session cookies and tokens under any salt."
                }
              ],
              "value": "An unauthenticated attacker sends one request with a wrong-typed parameter, or omits a header, and the secret key base or the compared secret is written into the application log and into crash_reason metadata forwarded to error trackers. Anyone who can read those logs then holds a key sufficient to mint session cookies and tokens under any salt."
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "NETWORK",
            "baseScore": 5.1,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "HIGH",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "NONE",
            "vulnConfidentialityImpact": "LOW",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-532",
              "description": "CWE-532 Insertion of Sensitive Information into Log File",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-10-23T09:56:58.885Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "name": "Secret key base exposed in stack trace arguments on wrong-typed Plug.Crypto arguments",
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/security/advisories/GHSA-ffw9-w85g-f2vh"
        },
        {
          "name": "EEF CNA record for CVE-2026-105963",
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-105963.html"
        },
        {
          "name": "OSV record EEF-CVE-2026-105963",
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-105963"
        },
        {
          "name": "Introducing commit 56000c3 in elixir-plug/plug",
          "tags": [
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/56000c33d8a0a2fbac491f8be06b9c5112bc2276"
        },
        {
          "name": "Fix commit aeaa90e in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/aeaa90e76b73ea90c3ecca9aae16fce71bd2a8d4"
        },
        {
          "name": "Introducing commit 2d078b7 in elixir-plug/plug_crypto",
          "tags": [
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug_crypto/commit/2d078b7b8264c565f0ff71235c515f4f46882dcf"
        },
        {
          "name": "Fix commit 9818874 in elixir-plug/plug_crypto",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug_crypto/commit/981887493dada0fce7003c61861c00dfbb0fc8c5"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Secret key base exposed in stack trace arguments on wrong-typed Plug.Crypto arguments",
      "workarounds": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eCheck argument types in the calling code before entering \u003ccode\u003ePlug.Crypto\u003c/code\u003e, so no head guard ever fails. Pass a token to \u003ccode\u003ePhoenix.Token.verify/4\u003c/code\u003e, \u003ccode\u003ePhoenix.Token.decrypt/4\u003c/code\u003e, \u003ccode\u003ePlug.Crypto.verify/4\u003c/code\u003e or \u003ccode\u003ePlug.Crypto.decrypt/4\u003c/code\u003e only when \u003ccode\u003eis_binary(token)\u003c/code\u003e holds, and treat anything else as an invalid token. Call \u003ccode\u003ePlug.Crypto.secure_compare/2\u003c/code\u003e only when both operands are binaries, treating a missing header or parameter as a failed comparison rather than passing nil.\u003c/p\u003e\n\u003cp\u003eWhere the leaked value matters more than the crash, configuring the error tracker to drop stack-frame arguments also keeps the secret out of the forwarded report. For Sentry this means not sending \u003ccode\u003evars\u003c/code\u003e with the crash report. This narrows exposure but leaves the value in the local error log.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Check argument types in the calling code before entering `Plug.Crypto`, so no head guard ever fails. Pass a token to `Phoenix.Token.verify/4`, `Phoenix.Token.decrypt/4`, `Plug.Crypto.verify/4` or `Plug.Crypto.decrypt/4` only when `is_binary(token)` holds, and treat anything else as an invalid token. Call `Plug.Crypto.secure_compare/2` only when both operands are binaries, treating a missing header or parameter as a failed comparison rather than passing nil.\n\nWhere the leaked value matters more than the crash, configuring the error tracker to drop stack-frame arguments also keeps the secret out of the forwarded report. For Sentry this means not sending `vars` with the crash report. This narrows exposure but leaves the value in the local error log."
            }
          ],
          "value": "Check argument types in the calling code before entering Plug.Crypto, so no head guard ever fails. Pass a token to Phoenix.Token.verify/4, Phoenix.Token.decrypt/4, Plug.Crypto.verify/4 or Plug.Crypto.decrypt/4 only when is_binary(token) holds, and treat anything else as an invalid token. Call Plug.Crypto.secure_compare/2 only when both operands are binaries, treating a missing header or parameter as a failed comparison rather than passing nil.\n\nWhere the leaked value matters more than the crash, configuring the error tracker to drop stack-frame arguments also keeps the secret out of the forwarded report. For Sentry this means not sending vars with the crash report. This narrows exposure but leaves the value in the local error log."
        }
      ],
      "x_proofOfConcept": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003col\u003e\n\u003cli\u003eRun an application that depends on \u003ccode\u003eplug_crypto\u003c/code\u003e and exposes a route calling \u003ccode\u003ePhoenix.Token.verify(secret_key_base, \"user auth\", conn.params[\"token\"])\u003c/code\u003e, plus a route calling \u003ccode\u003ePlug.Crypto.secure_compare(List.first(get_req_header(conn, \"x-api-key\")), api_key)\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eSend \u003ccode\u003eGET /verify?token[]=x\u003c/code\u003e. \u003ccode\u003ePlug.Parsers\u003c/code\u003e yields a list for the bracket syntax, so the token argument is a list.\u003c/li\u003e\n\u003cli\u003eObserve the 500 response and read the error log. The top frame prints \u003ccode\u003ePlug.Crypto.verify(\"SECRET_KEY_BASE_...\", \"user auth\", [\"x\"], [])\u003c/code\u003e with the secret key base in full, and the same frame is attached as \u003ccode\u003ecrash_reason\u003c/code\u003e Logger metadata.\u003c/li\u003e\n\u003cli\u003eSend \u003ccode\u003eGET /api\u003c/code\u003e with no \u003ccode\u003ex-api-key\u003c/code\u003e header. The header lookup yields nil, and the frame prints \u003ccode\u003ePlug.Crypto.secure_compare(nil, \"\u0026lt;configured API key\u0026gt;\")\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eA JSON body of \u003ccode\u003e{\"token\": 123}\u003c/code\u003e to the first route gives the same result with an integer argument.\u003c/li\u003e\n\u003c/ol\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "1. Run an application that depends on `plug_crypto` and exposes a route calling `Phoenix.Token.verify(secret_key_base, \"user auth\", conn.params[\"token\"])`, plus a route calling `Plug.Crypto.secure_compare(List.first(get_req_header(conn, \"x-api-key\")), api_key)`.\n2. Send `GET /verify?token[]=x`. `Plug.Parsers` yields a list for the bracket syntax, so the token argument is a list.\n3. Observe the 500 response and read the error log. The top frame prints `Plug.Crypto.verify(\"SECRET_KEY_BASE_...\", \"user auth\", [\"x\"], [])` with the secret key base in full, and the same frame is attached as `crash_reason` Logger metadata.\n4. Send `GET /api` with no `x-api-key` header. The header lookup yields nil, and the frame prints `Plug.Crypto.secure_compare(nil, \"\u003cconfigured API key\u003e\")`.\n5. A JSON body of `{\"token\": 123}` to the first route gives the same result with an integer argument."
            }
          ],
          "value": "* Run an application that depends on plug_crypto and exposes a route calling Phoenix.Token.verify(secret_key_base, \"user auth\", conn.params[\"token\"]), plus a route calling Plug.Crypto.secure_compare(List.first(get_req_header(conn, \"x-api-key\")), api_key).\n* Send GET /verify?token[]=x. Plug.Parsers yields a list for the bracket syntax, so the token argument is a list.\n* Observe the 500 response and read the error log. The top frame prints Plug.Crypto.verify(\"SECRET_KEY_BASE_...\", \"user auth\", [\"x\"], []) with the secret key base in full, and the same frame is attached as crash_reason Logger metadata.\n* Send GET /api with no x-api-key header. The header lookup yields nil, and the frame prints Plug.Crypto.secure_compare(nil, \"\u003cconfigured API key\u003e\").\n* A JSON body of {\"token\": 123} to the first route gives the same result with an integer argument."
        }
      ],
      "x_technicalAnalysis": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003e\u003cstrong\u003e1. Type checks in function-head guards.\u003c/strong\u003e Every public function in \u003ccode\u003ePlug.Crypto\u003c/code\u003e validates its arguments in a head guard, for example \u003ccode\u003esecure_compare/2\u003c/code\u003e with \u003ccode\u003ewhen is_binary(left) and is_binary(right)\u003c/code\u003e and \u003ccode\u003everify/4\u003c/code\u003e with \u003ccode\u003ewhen is_binary(key_base) and is_binary(salt) and is_binary(token)\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. The VM builds the error, not the library.\u003c/strong\u003e When no clause matches, the Erlang VM raises \u003ccode\u003eFunctionClauseError\u003c/code\u003e and the top stack frame holds the actual argument values. The library\u0027s \u003ccode\u003erescue ... reraise\u003c/code\u003e blocks and \u003ccode\u003ePlug.Crypto.prune_args_from_stacktrace/1\u003c/code\u003e only apply to exceptions raised inside a function body, so a guard failure never reaches them. In \u003ccode\u003eplug_crypto\u003c/code\u003e the same commit that added \u003ccode\u003eprune_args_from_stacktrace/1\u003c/code\u003e also added these guards.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Which value leaks.\u003c/strong\u003e \u003ccode\u003everify/4\u003c/code\u003e and \u003ccode\u003esign/4\u003c/code\u003e put the secret key base in the frame. \u003ccode\u003edecrypt/4\u003c/code\u003e has no \u003ccode\u003eis_binary(token)\u003c/code\u003e guard on its main clause, so the key is derived first and the failing guard belongs to \u003ccode\u003eMessageEncryptor.decrypt/4\u003c/code\u003e, placing the derived 32-byte key in the frame. \u003ccode\u003esecure_compare/2\u003c/code\u003e places the other operand in the frame, which is the server-side secret when a request value is nil.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e4. The frame reaches logs and error trackers.\u003c/strong\u003e Plug.Cowboy and Bandit write the formatted frame, arguments included, to the error log and attach it as \u003ccode\u003ecrash_reason\u003c/code\u003e Logger metadata. Error trackers forward it; Sentry\u0027s handler sends crash reports by default and serializes frame arguments as \u003ccode\u003evars\u003c/code\u003e.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "**1. Type checks in function-head guards.** Every public function in `Plug.Crypto` validates its arguments in a head guard, for example `secure_compare/2` with `when is_binary(left) and is_binary(right)` and `verify/4` with `when is_binary(key_base) and is_binary(salt) and is_binary(token)`.\n\n**2. The VM builds the error, not the library.** When no clause matches, the Erlang VM raises `FunctionClauseError` and the top stack frame holds the actual argument values. The library\u0027s `rescue ... reraise` blocks and `Plug.Crypto.prune_args_from_stacktrace/1` only apply to exceptions raised inside a function body, so a guard failure never reaches them. In `plug_crypto` the same commit that added `prune_args_from_stacktrace/1` also added these guards.\n\n**3. Which value leaks.** `verify/4` and `sign/4` put the secret key base in the frame. `decrypt/4` has no `is_binary(token)` guard on its main clause, so the key is derived first and the failing guard belongs to `MessageEncryptor.decrypt/4`, placing the derived 32-byte key in the frame. `secure_compare/2` places the other operand in the frame, which is the server-side secret when a request value is nil.\n\n**4. The frame reaches logs and error trackers.** Plug.Cowboy and Bandit write the formatted frame, arguments included, to the error log and attach it as `crash_reason` Logger metadata. Error trackers forward it; Sentry\u0027s handler sends crash reports by default and serializes frame arguments as `vars`."
            }
          ],
          "value": "1. Type checks in function-head guards. Every public function in Plug.Crypto validates its arguments in a head guard, for example secure_compare/2 with when is_binary(left) and is_binary(right) and verify/4 with when is_binary(key_base) and is_binary(salt) and is_binary(token).\n\n2. The VM builds the error, not the library. When no clause matches, the Erlang VM raises FunctionClauseError and the top stack frame holds the actual argument values. The library\u0027s rescue ... reraise blocks and Plug.Crypto.prune_args_from_stacktrace/1 only apply to exceptions raised inside a function body, so a guard failure never reaches them. In plug_crypto the same commit that added prune_args_from_stacktrace/1 also added these guards.\n\n3. Which value leaks. verify/4 and sign/4 put the secret key base in the frame. decrypt/4 has no is_binary(token) guard on its main clause, so the key is derived first and the failing guard belongs to MessageEncryptor.decrypt/4, placing the derived 32-byte key in the frame. secure_compare/2 places the other operand in the frame, which is the server-side secret when a request value is nil.\n\n4. The frame reaches logs and error trackers. Plug.Cowboy and Bandit write the formatted frame, arguments included, to the error log and attach it as crash_reason Logger metadata. Error trackers forward it; Sentry\u0027s handler sends crash reports by default and serializes frame arguments as vars."
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-105963",
    "datePublished": "2026-10-23T09:56:58.885Z",
    "dateReserved": "2026-10-06T10:30:01.805Z",
    "dateUpdated": "2026-10-23T13:39:29.887Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}

CVE-2026-56813 (GCVE-0-2026-56813)
Vulnerability from cvelistv5
Published
2026-07-10 12:51
Modified
2026-09-24 21:30
CWE
  • CWE-141 - Improper Neutralization of Parameter/Argument Delimiters
Summary
Improper Neutralization of Parameter/Argument Delimiters vulnerability in elixir-plug plug allows an attacker to inject or override HTTP cookie attributes. The Plug.Conn.Cookies.encode/2 function in lib/plug/conn/cookies.ex builds the Set-Cookie response header by interpolating the cookie value and its path, domain, same_site, and extra attributes directly into the header without neutralizing the ; delimiter that separates cookie attributes. An application that places attacker-controlled data into a cookie value or attribute (for example via Plug.Conn.put_resp_cookie/4 when reflecting a username or preference) lets an attacker inject a ; to append or override cookie attributes (such as Domain and Path scope, or dropping the Secure and HttpOnly flags), enabling cookie tossing and session fixation. Carriage return, line feed, and null bytes are rejected by Plug.Conn header validation, so HTTP response splitting is not possible, but attribute injection through ; is not prevented. This issue affects plug: from 0.1.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3.
Impacted products
Vendor Product Version
elixir-plug plug Version: 0.1.0   ≤
Version: 1.17.0   ≤
Version: 1.18.0   ≤
Version: 1.19.1   ≤
Version: 1.20.0   ≤
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug Version: f26876aa67aaeb38e616638aa3efbcc2fe2906a5
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-56813",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-07-10T14:43:36.298825Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-07-10T14:43:45.849Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Conn.Cookies\u0027",
            "\u0027Elixir.Plug.Conn\u0027"
          ],
          "packageName": "plug",
          "packageURL": "pkg:hex/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/conn/cookies.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Conn.Cookies\u0027:encode/2"
            },
            {
              "name": "\u0027Elixir.Plug.Conn\u0027:put_resp_cookie/4"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "1.16.6",
              "status": "affected",
              "version": "0.1.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.17.4",
              "status": "affected",
              "version": "1.17.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.18.5",
              "status": "affected",
              "version": "1.18.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.19.5",
              "status": "affected",
              "version": "1.19.1",
              "versionType": "semver"
            },
            {
              "lessThan": "1.20.3",
              "status": "affected",
              "version": "1.20.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Conn.Cookies\u0027",
            "\u0027Elixir.Plug.Conn\u0027"
          ],
          "packageName": "elixir-plug/plug",
          "packageURL": "pkg:github/elixir-plug/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/conn/cookies.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Conn.Cookies\u0027:encode/2"
            },
            {
              "name": "\u0027Elixir.Plug.Conn\u0027:put_resp_cookie/4"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "changes": [
                {
                  "at": "3f00dfad4e20ba88472e315c90a25742bf178f8e",
                  "status": "unaffected"
                },
                {
                  "at": "a6d1248659022749869963fd302687165ecf8c8b",
                  "status": "unaffected"
                },
                {
                  "at": "4167981747fe9ce75f374b94a28861ae950ea992",
                  "status": "unaffected"
                },
                {
                  "at": "149d9ed68fee0b4f77efd1e835ce5d785856697b",
                  "status": "unaffected"
                },
                {
                  "at": "eceb8315ce9a31ef784943a95a8624ebd1bc7e06",
                  "status": "unaffected"
                }
              ],
              "lessThan": "*",
              "status": "affected",
              "version": "f26876aa67aaeb38e616638aa3efbcc2fe2906a5",
              "versionType": "git"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.16.6",
                  "versionStartIncluding": "0.1.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.17.4",
                  "versionStartIncluding": "1.17.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.18.5",
                  "versionStartIncluding": "1.18.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.19.5",
                  "versionStartIncluding": "1.19.1",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.20.3",
                  "versionStartIncluding": "1.20.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Jos\u00e9 Valim"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "datePublic": "2026-07-10T12:51:08.000Z",
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eImproper Neutralization of Parameter/Argument Delimiters vulnerability in elixir-plug plug allows an attacker to inject or override HTTP cookie attributes.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003ePlug.Conn.Cookies.encode/2\u003c/code\u003e function in \u003ccode\u003elib/plug/conn/cookies.ex\u003c/code\u003e builds the \u003ccode\u003eSet-Cookie\u003c/code\u003e response header by interpolating the cookie value and its \u003ccode\u003epath\u003c/code\u003e, \u003ccode\u003edomain\u003c/code\u003e, \u003ccode\u003esame_site\u003c/code\u003e, and \u003ccode\u003eextra\u003c/code\u003e attributes directly into the header without neutralizing the \u003ccode\u003e;\u003c/code\u003e delimiter that separates cookie attributes.\u003c/p\u003e\n\u003cp\u003eAn application that places attacker-controlled data into a cookie value or attribute (for example via \u003ccode\u003ePlug.Conn.put_resp_cookie/4\u003c/code\u003e when reflecting a username or preference) lets an attacker inject a \u003ccode\u003e;\u003c/code\u003e to append or override cookie attributes (such as \u003ccode\u003eDomain\u003c/code\u003e and \u003ccode\u003ePath\u003c/code\u003e scope, or dropping the \u003ccode\u003eSecure\u003c/code\u003e and \u003ccode\u003eHttpOnly\u003c/code\u003e flags), enabling cookie tossing and session fixation. Carriage return, line feed, and null bytes are rejected by \u003ccode\u003ePlug.Conn\u003c/code\u003e header validation, so HTTP response splitting is not possible, but attribute injection through \u003ccode\u003e;\u003c/code\u003e is not prevented.\u003c/p\u003e\n\u003cp\u003eThis issue affects plug: from 0.1.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Improper Neutralization of Parameter/Argument Delimiters vulnerability in elixir-plug plug allows an attacker to inject or override HTTP cookie attributes.\n\nThe `Plug.Conn.Cookies.encode/2` function in `lib/plug/conn/cookies.ex` builds the `Set-Cookie` response header by interpolating the cookie value and its `path`, `domain`, `same_site`, and `extra` attributes directly into the header without neutralizing the `;` delimiter that separates cookie attributes.\n\nAn application that places attacker-controlled data into a cookie value or attribute (for example via `Plug.Conn.put_resp_cookie/4` when reflecting a username or preference) lets an attacker inject a `;` to append or override cookie attributes (such as `Domain` and `Path` scope, or dropping the `Secure` and `HttpOnly` flags), enabling cookie tossing and session fixation. Carriage return, line feed, and null bytes are rejected by `Plug.Conn` header validation, so HTTP response splitting is not possible, but attribute injection through `;` is not prevented.\n\nThis issue affects plug: from 0.1.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3."
            }
          ],
          "value": "Improper Neutralization of Parameter/Argument Delimiters vulnerability in elixir-plug plug allows an attacker to inject or override HTTP cookie attributes.\n\nThe Plug.Conn.Cookies.encode/2 function in lib/plug/conn/cookies.ex builds the Set-Cookie response header by interpolating the cookie value and its path, domain, same_site, and extra attributes directly into the header without neutralizing the ; delimiter that separates cookie attributes.\n\nAn application that places attacker-controlled data into a cookie value or attribute (for example via Plug.Conn.put_resp_cookie/4 when reflecting a username or preference) lets an attacker inject a ; to append or override cookie attributes (such as Domain and Path scope, or dropping the Secure and HttpOnly flags), enabling cookie tossing and session fixation. Carriage return, line feed, and null bytes are rejected by Plug.Conn header validation, so HTTP response splitting is not possible, but attribute injection through ; is not prevented.\n\nThis issue affects plug: from 0.1.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-61",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-61 Session Fixation"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "PRESENT",
            "attackVector": "LOCAL",
            "baseScore": 2.1,
            "baseSeverity": "LOW",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "LOW",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "NONE",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "LOW",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-141",
              "description": "CWE-141 Improper Neutralization of Parameter/Argument Delimiters",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-24T21:30:13.749Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/security/advisories/GHSA-wpmj-jh88-rpgm"
        },
        {
          "name": "EEF CNA record for CVE-2026-56813",
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-56813.html"
        },
        {
          "name": "OSV record EEF-CVE-2026-56813",
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-56813"
        },
        {
          "name": "Introducing commit f26876a in elixir-plug/plug",
          "tags": [
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/f26876aa67aaeb38e616638aa3efbcc2fe2906a5"
        },
        {
          "name": "Fix commit 3f00dfa in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/3f00dfad4e20ba88472e315c90a25742bf178f8e"
        },
        {
          "name": "Fix commit a6d1248 in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/a6d1248659022749869963fd302687165ecf8c8b"
        },
        {
          "name": "Fix commit 4167981 in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/4167981747fe9ce75f374b94a28861ae950ea992"
        },
        {
          "name": "Fix commit 149d9ed in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/149d9ed68fee0b4f77efd1e835ce5d785856697b"
        },
        {
          "name": "Fix commit eceb831 in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/eceb8315ce9a31ef784943a95a8624ebd1bc7e06"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Cookie attribute injection in Plug.Conn.Cookies.encode/2",
      "workarounds": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eValidate or reject the \u003ccode\u003e;\u003c/code\u003e delimiter in any untrusted data before passing it as a cookie value or attribute to \u003ccode\u003ePlug.Conn.put_resp_cookie/4\u003c/code\u003e or \u003ccode\u003ePlug.Conn.Cookies.encode/2\u003c/code\u003e. Carriage return, line feed, and null bytes are already rejected by \u003ccode\u003ePlug.Conn\u003c/code\u003e header validation.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Validate or reject the `;` delimiter in any untrusted data before passing it as a cookie value or attribute to `Plug.Conn.put_resp_cookie/4` or `Plug.Conn.Cookies.encode/2`. Carriage return, line feed, and null bytes are already rejected by `Plug.Conn` header validation."
            }
          ],
          "value": "Validate or reject the ; delimiter in any untrusted data before passing it as a cookie value or attribute to Plug.Conn.put_resp_cookie/4 or Plug.Conn.Cookies.encode/2. Carriage return, line feed, and null bytes are already rejected by Plug.Conn header validation."
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-56813",
    "datePublished": "2026-07-10T12:51:08.758Z",
    "dateReserved": "2026-06-23T12:29:02.507Z",
    "dateUpdated": "2026-09-24T21:30:13.749Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}

CVE-2026-56814 (GCVE-0-2026-56814)
Vulnerability from cvelistv5
Published
2026-07-10 11:14
Modified
2026-09-24 21:31
CWE
  • CWE-770 - Allocation of Resources Without Limits or Throttling
Summary
Plug.Parsers.MULTIPART, the multipart request-body parser used to handle file uploads and multipart forms, does not enforce its :length budget against all consumed resources, allowing an unauthenticated remote attacker to cause denial of service. The parser charges the :length limit only for part body bytes; part header bytes are never counted, and a part with an empty body costs zero. Because every part whose Content-Disposition carries a non-empty filename creates a fresh temporary file (via Plug.Upload) and retains a Plug.Upload struct for the duration of the request, an attacker can send a single request composed of many empty-body file parts. Such a request stays well under the configured :length limit (8,000,000 bytes by default) while creating one temporary file per part, leading to inode and disk exhaustion and unbounded memory growth. Any application using Plug.Parsers with the :multipart parser is affected, and no authentication is required, only reachability of a multipart endpoint over HTTP. This vulnerability is associated with program files lib/plug/parsers/multipart.ex and program routines Plug.Parsers.MULTIPART.parse_multipart/2, Plug.Parsers.MULTIPART.parse_multipart_headers/5, Plug.Parsers.MULTIPART.parse_multipart_body/4, and Plug.Parsers.MULTIPART.parse_multipart_file/4. This issue affects plug: from 1.4.0-rc.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3.
Impacted products
Vendor Product Version
elixir-plug plug Version: 1.4.0-rc.0   ≤
Version: 1.17.0   ≤
Version: 1.18.0   ≤
Version: 1.19.1   ≤
Version: 1.20.0   ≤
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug Version: c52b2f32c90bccd718202bafccb5f95594e30183
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-56814",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "yes"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-07-10T14:03:11.744626Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-07-10T14:03:28.156Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Parsers.MULTIPART\u0027"
          ],
          "packageName": "plug",
          "packageURL": "pkg:hex/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/parsers/multipart.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart/2"
            },
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart_headers/5"
            },
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart_body/4"
            },
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart_file/4"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "1.16.6",
              "status": "affected",
              "version": "1.4.0-rc.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.17.4",
              "status": "affected",
              "version": "1.17.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.18.5",
              "status": "affected",
              "version": "1.18.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.19.5",
              "status": "affected",
              "version": "1.19.1",
              "versionType": "semver"
            },
            {
              "lessThan": "1.20.3",
              "status": "affected",
              "version": "1.20.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Parsers.MULTIPART\u0027"
          ],
          "packageName": "elixir-plug/plug",
          "packageURL": "pkg:github/elixir-plug/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/parsers/multipart.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart/2"
            },
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart_headers/5"
            },
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart_body/4"
            },
            {
              "name": "\u0027Elixir.Plug.Parsers.MULTIPART\u0027:parse_multipart_file/4"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "changes": [
                {
                  "at": "981597d3a4271ede64373c7a731702a42c500dd6",
                  "status": "unaffected"
                },
                {
                  "at": "56edca2ce35fe5589cd581644d8a4493fa5f484e",
                  "status": "unaffected"
                },
                {
                  "at": "0ee8afcc61466dc5f7a8f048d0632c899165b81f",
                  "status": "unaffected"
                },
                {
                  "at": "cae36053350e5215a4e0ca33cd130af9c5fc6364",
                  "status": "unaffected"
                },
                {
                  "at": "f7effaed811c00b5f5bf817936bfd9c5df27b7dc",
                  "status": "unaffected"
                },
                {
                  "at": "df97d3f17f808a9916a7700a701fb85314559d56",
                  "status": "unaffected"
                }
              ],
              "lessThan": "*",
              "status": "affected",
              "version": "c52b2f32c90bccd718202bafccb5f95594e30183",
              "versionType": "git"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.16.6",
                  "versionStartIncluding": "1.4.0-rc.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.17.4",
                  "versionStartIncluding": "1.17.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.18.5",
                  "versionStartIncluding": "1.18.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.19.5",
                  "versionStartIncluding": "1.19.1",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.20.3",
                  "versionStartIncluding": "1.20.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Jos\u00e9 Valim"
        }
      ],
      "datePublic": "2026-07-10T11:14:35.000Z",
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003e\u003ccode\u003ePlug.Parsers.MULTIPART\u003c/code\u003e, the multipart request-body parser used to handle file uploads and multipart forms, does not enforce its \u003ccode\u003e:length\u003c/code\u003e budget against all consumed resources, allowing an unauthenticated remote attacker to cause denial of service. The parser charges the \u003ccode\u003e:length\u003c/code\u003e limit only for part body bytes; part header bytes are never counted, and a part with an empty body costs zero.\u003c/p\u003e\n\u003cp\u003eBecause every part whose \u003ccode\u003eContent-Disposition\u003c/code\u003e carries a non-empty \u003ccode\u003efilename\u003c/code\u003e creates a fresh temporary file (via \u003ccode\u003ePlug.Upload\u003c/code\u003e) and retains a \u003ccode\u003ePlug.Upload\u003c/code\u003e struct for the duration of the request, an attacker can send a single request composed of many empty-body file parts. Such a request stays well under the configured \u003ccode\u003e:length\u003c/code\u003e limit (8,000,000 bytes by default) while creating one temporary file per part, leading to inode and disk exhaustion and unbounded memory growth. Any application using \u003ccode\u003ePlug.Parsers\u003c/code\u003e with the \u003ccode\u003e:multipart\u003c/code\u003e parser is affected, and no authentication is required, only reachability of a multipart endpoint over HTTP.\u003c/p\u003e\n\u003cp\u003eThis vulnerability is associated with program files \u003ccode\u003elib/plug/parsers/multipart.ex\u003c/code\u003e and program routines \u003ccode\u003ePlug.Parsers.MULTIPART.parse_multipart/2\u003c/code\u003e, \u003ccode\u003ePlug.Parsers.MULTIPART.parse_multipart_headers/5\u003c/code\u003e, \u003ccode\u003ePlug.Parsers.MULTIPART.parse_multipart_body/4\u003c/code\u003e, and \u003ccode\u003ePlug.Parsers.MULTIPART.parse_multipart_file/4\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis issue affects plug: from 1.4.0-rc.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "`Plug.Parsers.MULTIPART`, the multipart request-body parser used to handle file uploads and multipart forms, does not enforce its `:length` budget against all consumed resources, allowing an unauthenticated remote attacker to cause denial of service. The parser charges the `:length` limit only for part body bytes; part header bytes are never counted, and a part with an empty body costs zero.\n\nBecause every part whose `Content-Disposition` carries a non-empty `filename` creates a fresh temporary file (via `Plug.Upload`) and retains a `Plug.Upload` struct for the duration of the request, an attacker can send a single request composed of many empty-body file parts. Such a request stays well under the configured `:length` limit (8,000,000 bytes by default) while creating one temporary file per part, leading to inode and disk exhaustion and unbounded memory growth. Any application using `Plug.Parsers` with the `:multipart` parser is affected, and no authentication is required, only reachability of a multipart endpoint over HTTP.\n\nThis vulnerability is associated with program files `lib/plug/parsers/multipart.ex` and program routines `Plug.Parsers.MULTIPART.parse_multipart/2`, `Plug.Parsers.MULTIPART.parse_multipart_headers/5`, `Plug.Parsers.MULTIPART.parse_multipart_body/4`, and `Plug.Parsers.MULTIPART.parse_multipart_file/4`.\n\nThis issue affects plug: from 1.4.0-rc.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3."
            }
          ],
          "value": "Plug.Parsers.MULTIPART, the multipart request-body parser used to handle file uploads and multipart forms, does not enforce its :length budget against all consumed resources, allowing an unauthenticated remote attacker to cause denial of service. The parser charges the :length limit only for part body bytes; part header bytes are never counted, and a part with an empty body costs zero.\n\nBecause every part whose Content-Disposition carries a non-empty filename creates a fresh temporary file (via Plug.Upload) and retains a Plug.Upload struct for the duration of the request, an attacker can send a single request composed of many empty-body file parts. Such a request stays well under the configured :length limit (8,000,000 bytes by default) while creating one temporary file per part, leading to inode and disk exhaustion and unbounded memory growth. Any application using Plug.Parsers with the :multipart parser is affected, and no authentication is required, only reachability of a multipart endpoint over HTTP.\n\nThis vulnerability is associated with program files lib/plug/parsers/multipart.ex and program routines Plug.Parsers.MULTIPART.parse_multipart/2, Plug.Parsers.MULTIPART.parse_multipart_headers/5, Plug.Parsers.MULTIPART.parse_multipart_body/4, and Plug.Parsers.MULTIPART.parse_multipart_file/4.\n\nThis issue affects plug: from 1.4.0-rc.0 before 1.16.6, from 1.17.0 before 1.17.4, from 1.18.0 before 1.18.5, from 1.19.1 before 1.19.5, and from 1.20.0 before 1.20.3."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-130",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-130 Excessive Allocation"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "NETWORK",
            "baseScore": 6.9,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "LOW",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-770",
              "description": "CWE-770 Allocation of Resources Without Limits or Throttling",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-24T21:31:15.419Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/security/advisories/GHSA-95qv-c9g9-rm63"
        },
        {
          "name": "EEF CNA record for CVE-2026-56814",
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-56814.html"
        },
        {
          "name": "OSV record EEF-CVE-2026-56814",
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-56814"
        },
        {
          "name": "Introducing commit c52b2f3 in elixir-plug/plug",
          "tags": [
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/c52b2f32c90bccd718202bafccb5f95594e30183"
        },
        {
          "name": "Fix commit 981597d in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/981597d3a4271ede64373c7a731702a42c500dd6"
        },
        {
          "name": "Fix commit 56edca2 in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/56edca2ce35fe5589cd581644d8a4493fa5f484e"
        },
        {
          "name": "Fix commit 0ee8afc in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/0ee8afcc61466dc5f7a8f048d0632c899165b81f"
        },
        {
          "name": "Fix commit cae3605 in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/cae36053350e5215a4e0ca33cd130af9c5fc6364"
        },
        {
          "name": "Fix commit f7effae in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/f7effaed811c00b5f5bf817936bfd9c5df27b7dc"
        },
        {
          "name": "Fix commit df97d3f in elixir-plug/plug",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/df97d3f17f808a9916a7700a701fb85314559d56"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Plug: multipart :length limit is not charged for part headers, enabling unbounded temp-file creation (denial of service)"
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-56814",
    "datePublished": "2026-07-10T11:14:35.574Z",
    "dateReserved": "2026-06-23T12:29:02.507Z",
    "dateUpdated": "2026-09-24T21:31:15.419Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}

CVE-2026-54892 (GCVE-0-2026-54892)
Vulnerability from cvelistv5
Published
2026-06-23 12:31
Modified
2026-06-23 18:21
CWE
  • CWE-407 - Inefficient Algorithmic Complexity
Summary
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.decode_each/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.decode_each/2, Plug.Conn.Query.split_keys/6, Plug.Conn.Query.insert_keys/3, and Plug.Conn.Query.finalize_pointer/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.
Impacted products
Vendor Product Version
elixir-plug plug Version: 1.15.0   ≤
Version: 1.16.0   ≤
Version: 1.17.0   ≤
Version: 1.18.0   ≤
Version: 1.19.0   ≤
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug Version: 712b875d3442c765d8d37e546ffd5ad9f8afcc55
    cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-54892",
                "options": [
                  {
                    "Exploitation": "poc"
                  },
                  {
                    "Automatable": "yes"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-06-23T13:03:58.893269Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-06-23T13:04:27.014Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "references": [
          {
            "tags": [
              "exploit"
            ],
            "url": "https://github.com/elixir-plug/plug/security/advisories/GHSA-j43x-5hjq-rgxf"
          }
        ],
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Conn.Query\u0027"
          ],
          "packageName": "plug",
          "packageURL": "pkg:hex/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/conn/query.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:decode/4"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:decode_each/2"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:split_keys/6"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:insert_keys/3"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:finalize_pointer/2"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "1.15.5",
              "status": "affected",
              "version": "1.15.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.16.4",
              "status": "affected",
              "version": "1.16.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.17.2",
              "status": "affected",
              "version": "1.17.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.18.3",
              "status": "affected",
              "version": "1.18.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.19.3",
              "status": "affected",
              "version": "1.19.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Plug.Conn.Query\u0027"
          ],
          "packageName": "elixir-plug/plug",
          "packageURL": "pkg:github/elixir-plug/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/conn/query.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:decode/4"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:decode_each/2"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:split_keys/6"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:insert_keys/3"
            },
            {
              "name": "\u0027Elixir.Plug.Conn.Query\u0027:finalize_pointer/2"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "changes": [
                {
                  "at": "c317d08fdcf96e17931f7419275b2b8c4bf3e951",
                  "status": "unaffected"
                },
                {
                  "at": "9c5d37c440eaae92869eed7c014c47266744fadb",
                  "status": "unaffected"
                },
                {
                  "at": "d737eb236f17e31a36290e39f9ef3cd86a1343bd",
                  "status": "unaffected"
                },
                {
                  "at": "d4e5568392a4b29e545b91e12e87d6098f976145",
                  "status": "unaffected"
                },
                {
                  "at": "a61124aa625d819a218fb07f90afbac8aa85eb0e",
                  "status": "unaffected"
                }
              ],
              "lessThan": "*",
              "status": "affected",
              "version": "712b875d3442c765d8d37e546ffd5ad9f8afcc55",
              "versionType": "git"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.15.5",
                  "versionStartIncluding": "1.15.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.16.4",
                  "versionStartIncluding": "1.16.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.17.2",
                  "versionStartIncluding": "1.17.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.18.3",
                  "versionStartIncluding": "1.18.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:elixir-plug:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.19.3",
                  "versionStartIncluding": "1.19.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Braidon Whatley"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Jos\u00e9 Valim"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eInefficient algorithmic complexity in Plug\u0027s nested-parameter decoder allows an unauthenticated remote attacker to cause denial of service. \u003ctt\u003ePlug.Conn.Query.decode/4\u003c/tt\u003e (and \u003ctt\u003ePlug.Conn.Query.decode_each/2\u003c/tt\u003e) parse query strings and \u003ctt\u003eapplication/x-www-form-urlencoded\u003c/tt\u003e request bodies. When a key contains many bracketed segments such as \u003ctt\u003ea[a][a][a]=1\u003c/tt\u003e, 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.\u003c/p\u003e\u003cp\u003eWith the default \u003ctt\u003ePlug.Parsers.URLENCODED\u003c/tt\u003e 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.\u003c/p\u003e\u003cp\u003eThis vulnerability is associated with program files \u003ctt\u003elib/plug/conn/query.ex\u003c/tt\u003e and program routines \u003ctt\u003ePlug.Conn.Query.decode/4\u003c/tt\u003e, \u003ctt\u003ePlug.Conn.Query.decode_each/2\u003c/tt\u003e, \u003ctt\u003ePlug.Conn.Query.split_keys/6\u003c/tt\u003e, \u003ctt\u003ePlug.Conn.Query.insert_keys/3\u003c/tt\u003e, and \u003ctt\u003ePlug.Conn.Query.finalize_pointer/2\u003c/tt\u003e.\u003c/p\u003e\u003cp\u003eThis issue affects plug from 1.15.0 before 1.15.5, 1.16.4, 1.17.2, 1.18.3, and 1.19.3.\u003c/p\u003e"
            }
          ],
          "value": "Inefficient algorithmic complexity in Plug\u0027s nested-parameter decoder allows an unauthenticated remote attacker to cause denial of service. Plug.Conn.Query.decode/4 (and Plug.Conn.Query.decode_each/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.\n\nWith 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.\n\nThis vulnerability is associated with program files lib/plug/conn/query.ex and program routines Plug.Conn.Query.decode/4, Plug.Conn.Query.decode_each/2, Plug.Conn.Query.split_keys/6, Plug.Conn.Query.insert_keys/3, and Plug.Conn.Query.finalize_pointer/2.\n\nThis issue affects plug from 1.15.0 before 1.15.5, 1.16.4, 1.17.2, 1.18.3, and 1.19.3."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-229",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-229 Serialized Data Parameter Blowup"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "NETWORK",
            "baseScore": 8.7,
            "baseSeverity": "HIGH",
            "privilegesRequired": "NONE",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "HIGH",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "NONE"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-407",
              "description": "CWE-407 Inefficient Algorithmic Complexity",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-06-23T18:21:14.232Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/security/advisories/GHSA-j43x-5hjq-rgxf"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-54892.html"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-54892"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/c317d08fdcf96e17931f7419275b2b8c4bf3e951"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/9c5d37c440eaae92869eed7c014c47266744fadb"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/d737eb236f17e31a36290e39f9ef3cd86a1343bd"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/d4e5568392a4b29e545b91e12e87d6098f976145"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/a61124aa625d819a218fb07f90afbac8aa85eb0e"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Plug: quadratic-time decoding of nested query/body parameters enables denial of service",
      "x_generator": {
        "engine": "cvelib 1.8.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-54892",
    "datePublished": "2026-06-23T12:31:12.629Z",
    "dateReserved": "2026-06-16T10:47:13.915Z",
    "dateUpdated": "2026-06-23T18:21:14.232Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}

CVE-2026-8468 (GCVE-0-2026-8468)
Vulnerability from cvelistv5
Published
2026-05-14 10:29
Modified
2026-05-27 15:41
CWE
  • CWE-770 - Allocation of Resources Without Limits or Throttling
Summary
Allocation of Resources Without Limits or Throttling vulnerability in plug_project plug allows denial of service via unbounded buffer accumulation in multipart header parsing. 'Elixir.Plug.Conn':read_part_headers/2 in lib/plug/conn.ex does not obey its :length parameter. There is no upper bound on the size of the accumulated buffer. By contrast, the sibling function read_part_body has an explicit byte_size(acc) > length guard that stops accumulation once a limit is reached. No such guard exists in read_part_headers. An unauthenticated remote attacker can exhaust server memory by sending a crafted multipart/form-data request, causing a denial of service. This issue affects plug from 1.4.0 before 1.15.4, 1.16.3, 1.17.1, 1.18.2, and 1.19.2.
Impacted products
Vendor Product Version
elixir-plug plug Version: 1.4.0   ≤
Version: 1.16.0   ≤
Version: 1.17.0   ≤
Version: 1.18.0   ≤
Version: 1.19.0   ≤
    cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
   elixir-plug plug Version: c52b2f32c90bccd718202bafccb5f95594e30183
    cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-8468",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-05-14T17:53:52.632415Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-05-14T17:54:23.302Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "Elixir.Plug.Conn"
          ],
          "packageName": "plug",
          "packageURL": "pkg:hex/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/conn.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Conn\u0027:read_part_headers/2"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "lessThan": "1.15.4",
              "status": "affected",
              "version": "1.4.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.16.3",
              "status": "affected",
              "version": "1.16.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.17.1",
              "status": "affected",
              "version": "1.17.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.18.2",
              "status": "affected",
              "version": "1.18.0",
              "versionType": "semver"
            },
            {
              "lessThan": "1.19.2",
              "status": "affected",
              "version": "1.19.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "Elixir.Plug.Conn"
          ],
          "packageName": "elixir-plug/plug",
          "packageURL": "pkg:github/elixir-plug/plug",
          "product": "plug",
          "programFiles": [
            "lib/plug/conn.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Plug.Conn\u0027:read_part_headers/2"
            }
          ],
          "repo": "https://github.com/elixir-plug/plug",
          "vendor": "elixir-plug",
          "versions": [
            {
              "changes": [
                {
                  "at": "2cb7958d33030aa826b0c7404375844d4593d43a",
                  "status": "unaffected"
                },
                {
                  "at": "aa69c5ece99c40ded88b8c6581ecc86664b0b734",
                  "status": "unaffected"
                },
                {
                  "at": "d5dfffe25e975585227b1b85d247b0d14164bc45",
                  "status": "unaffected"
                },
                {
                  "at": "df812a1527bae9e941965e897308a2b8bbf83a94",
                  "status": "unaffected"
                },
                {
                  "at": "33858427c7f2737d560a2e40a0c9a9270d77d1d7",
                  "status": "unaffected"
                }
              ],
              "lessThan": "*",
              "status": "affected",
              "version": "c52b2f32c90bccd718202bafccb5f95594e30183",
              "versionType": "git"
            }
          ]
        }
      ],
      "configurations": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eThe application must use \u003ctt\u003ePlug.Parsers\u003c/tt\u003e with the \u003ctt\u003e:multipart\u003c/tt\u003e parser, or otherwise call \u003ctt\u003ePlug.Conn.read_part_headers/2\u003c/tt\u003e to process \u003ctt\u003emultipart/form-data\u003c/tt\u003e request bodies. Deployments that do not handle multipart uploads are not affected.\u003c/p\u003e"
            }
          ],
          "value": "The application must use Plug.Parsers with the :multipart parser, or otherwise call Plug.Conn.read_part_headers/2 to process multipart/form-data request bodies. Deployments that do not handle multipart uploads are not affected."
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.15.4",
                  "versionStartIncluding": "1.4.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.16.3",
                  "versionStartIncluding": "1.16.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.17.1",
                  "versionStartIncluding": "1.17.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.18.2",
                  "versionStartIncluding": "1.18.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:a:plug_project:plug:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.19.2",
                  "versionStartIncluding": "1.19.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Jos\u00e9 Valim"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Jos\u00e9 Valim"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eAllocation of Resources Without Limits or Throttling vulnerability in plug_project plug allows denial of service via unbounded buffer accumulation in multipart header parsing.\u003c/p\u003e\u003cp\u003e\u003ctt\u003e\u0027Elixir.Plug.Conn\u0027:read_part_headers/2\u003c/tt\u003e in \u003ctt\u003elib/plug/conn.ex\u003c/tt\u003e does not obey its \u003ctt\u003e:length\u003c/tt\u003e parameter. There is no upper bound on the size of the accumulated buffer. By contrast, the sibling function \u003ctt\u003eread_part_body\u003c/tt\u003e has an explicit \u003ctt\u003ebyte_size(acc) \u0026gt; length\u003c/tt\u003e guard that stops accumulation once a limit is reached. No such guard exists in \u003ctt\u003eread_part_headers\u003c/tt\u003e. An unauthenticated remote attacker can exhaust server memory by sending a crafted \u003ctt\u003emultipart/form-data\u003c/tt\u003e request, causing a denial of service.\u003c/p\u003e\u003cp\u003eThis issue affects plug from 1.4.0 before 1.15.4, 1.16.3, 1.17.1, 1.18.2, and 1.19.2.\u003c/p\u003e"
            }
          ],
          "value": "Allocation of Resources Without Limits or Throttling vulnerability in plug_project plug allows denial of service via unbounded buffer accumulation in multipart header parsing.\n\n\u0027Elixir.Plug.Conn\u0027:read_part_headers/2 in lib/plug/conn.ex does not obey its :length parameter. There is no upper bound on the size of the accumulated buffer. By contrast, the sibling function read_part_body has an explicit byte_size(acc) \u003e length guard that stops accumulation once a limit is reached. No such guard exists in read_part_headers. An unauthenticated remote attacker can exhaust server memory by sending a crafted multipart/form-data request, causing a denial of service.\n\nThis issue affects plug from 1.4.0 before 1.15.4, 1.16.3, 1.17.1, 1.18.2, and 1.19.2."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-130",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-130 Excessive Allocation"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "attackComplexity": "LOW",
            "attackRequirements": "PRESENT",
            "attackVector": "NETWORK",
            "baseScore": 8.2,
            "baseSeverity": "HIGH",
            "privilegesRequired": "NONE",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "vectorString": "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",
            "version": "4.0",
            "vulnAvailabilityImpact": "HIGH",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "NONE"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-770",
              "description": "CWE-770 Allocation of Resources Without Limits or Throttling",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-05-27T15:41:29.241Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/elixir-plug/plug/security/advisories/GHSA-468c-vq7p-gh64"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-8468.html"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-8468"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-8466.html"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/2cb7958d33030aa826b0c7404375844d4593d43a"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/aa69c5ece99c40ded88b8c6581ecc86664b0b734"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/d5dfffe25e975585227b1b85d247b0d14164bc45"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/df812a1527bae9e941965e897308a2b8bbf83a94"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/elixir-plug/plug/commit/33858427c7f2737d560a2e40a0c9a9270d77d1d7"
        }
      ],
      "source": {
        "discovery": "INTERNAL"
      },
      "title": "Unbounded buffer accumulation in multipart header parsing causes denial of service in plug",
      "x_generator": {
        "engine": "cvelib 1.8.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-8468",
    "datePublished": "2026-05-14T10:29:51.062Z",
    "dateReserved": "2026-05-13T11:44:42.164Z",
    "dateUpdated": "2026-05-27T15:41:29.241Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}