GHSA-474x-hrwr-fgx4

Suggest an improvement
Source
https://github.com/advisories/GHSA-474x-hrwr-fgx4
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-474x-hrwr-fgx4/GHSA-474x-hrwr-fgx4.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-474x-hrwr-fgx4
Aliases
  • CVE-2026-126066
Published
2026-11-10T21:09:44Z
Modified
2026-11-10T21:15:03Z
Severity
  • 3.7 (Low) CVSS_V3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L CVSS Calculator
Summary
fast-xml-parser: Quadratic CPU consumption scanning unterminated stop-node tags
Details

Summary

With the non-default stopNodes option, a stop node's body with many "<a " fragments and no closing ">" anywhere after makes readStopNodeData() rescan the entire remaining input from every "<". The failed lookahead is neither cached nor bounded, so n fragments cost O(n²) before the parser throws. Availability-only (CPU exhaustion), needs the non-default stopNodes option — not benchmarked yet, see Proof of Concept.

Details

CWE-407 — Inefficient Algorithmic Complexity

Code

  • OrderedObjParser.js:520 — parseXml() calls readStopNodeData() after a matching stop node opens
  • OrderedObjParser.js:810 — calls readTagExp() for every non-special <
  • OrderedObjParser.js:688-722 — tagExpWithClosingIndex() scans to end-of-input and returns undefined when no > exists
  • OrderedObjParser.js:812-818 — on failure, i isn't advanced, so the next < repeats the same full scan
  • OrderedObjParser.js:423 — the main parse loop throws immediately on the same failure; only the stop-node path retries

Root cause: a failed closing-> lookahead is neither cached nor bounded — n copies of <a with no later > means n scans over the remaining input, O(n²) work, before it finally throws.

Fix

  1. Throw immediately in readStopNodeData() when readTagExp() returns undefined
  2. Or break the loop on the first failed scan
  3. Or find the next > once and reuse/bound that result
  4. Add a test asserting near-linear scaling when payload size doubles

Proof of concept

Not benchmarked — static-analysis finding, confidence 0.5.

To confirm: configure stopNodes matching a root element. Build input as '<stop>' + '<a '.repeat(n). Time parse() until it throws Unexpected end of <tag>. Start around n=10,000 and double it — quadratic should show ~4x time per doubling, linear ~2x. Control: same input with a > present, or stopNodes unset.

Impact

CPU-exhaustion DoS in Node.js services parsing untrusted XML with stopNodes enabled. A ~100KB payload is estimated at ~10⁹ character operations (roughly a second or more of blocked event loop) — analytical estimate, not a benchmark. No confidentiality/integrity impact. CVSS 3.1: AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L (3.7, Low).

Database specific
{
    "cwe_ids": [
        "CWE-407"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-11-10T21:09:44Z",
    "nvd_published_at": null,
    "severity": "LOW"
}
References

Affected packages

npm / fast-xml-parser

Package

Name
fast-xml-parser
View open source insights on deps.dev
Purl
pkg:npm/fast-xml-parser

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
5.12.0

Database specific

last_known_affected_version_range
"<= 5.11.2"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-474x-hrwr-fgx4/GHSA-474x-hrwr-fgx4.json"