CVE-2026-53550: js-yaml: Quadratic-complexity DoS in merge key handling via repeated aliases

Published Jun 15, 2026
·
Updated

Summary A crafted YAML document can trigger algorithmic CPU exhaustion in js-yaml merge-key processing (<<) by repeating the same alias many times in a merge sequence. This causes quadratic parse-time behavior relative to input size and can block a Node.js worker/event loop for seconds with a relatively small payload (tens of KB), resulting in denial of service.

Details The issue is in merge handling inside lib/loader.js:

- storeMappingPair(...) iterates every element of a merge sequence when key tag is tag:yaml.org,2002:merge. - For each element, it calls mergeMappings(...). - mergeMappings(...) computes Object.keys(source) and performs hasOwnProperty.call(destination, key) checks for each key.

When input is of the form:

a: &a {k0:0, k1:0, ..., kK:0} b: {<<: [a, a, a, ... repeated M times ...]} all a entries refer to the same anchored object. After the first merge, subsequent merges are semantically no-ops, but the parser still reprocesses all keys each time. Resulting work is O(K M), while input size is O(K + M), giving quadratic scaling as payload grows. Relevant code path: lib/loader.js in storeMappingPair(...) merge branch (keyTag === 'tag:yaml.org,2002:merge') lib/loader.js mergeMappings(...)

Root cause File: lib/loader.js Function: storeMappingPair(state, result, overridableKeys, keyTag, keyNode, valueNode, startLine, startLineStart, startPos) Lines: ~359-366

if (keyTag === 'tag:yaml.org,2002:merge') { if (Array.isArray(valueNode)) { for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { mergeMappings(state, result, valueNode[index], overridableKeys); } } else { mergeMappings(state, result, valueNode, overridableKeys); } }

When the merge value is a sequence (YAML 1.1 <<: [ a, a, ... ]), each element is handed to mergeMappings() without deduplication. mergeMappings() then does

sourceKeys = Object.keys(source); for (index = 0; index < sourceKeys.length; index += 1) { key = sourceKeys[index]; if (!hasOwnProperty.call(destination, key)) { setProperty(destination, key, source[key]); overridableKeys[key] = true; } }

Every alias reference in the sequence resolves (by design) to the SAME object via state.anchorMap. After the first merge, every subsequent merge of that same reference is a pure no-op semantically, but still performs:

one Object.keys(source) call (O(K)) K hasOwnProperty.call checks on the destination

Total: M K hasOwnProperty checks + M Object.keys allocations, while the final object and all observable side effects are identical to a single merge.

YAML semantics for <<: are idempotent and commutative over duplicate sources, so collapsing duplicates preserves behavior exactly; this isn't a spec trade-off.

PoC Environment: js-yaml version: 4.1.1 Node.js: v24.5.0 Platform: arm64 macOS (reproduced consistently) Reproduction script: Create many keys in one anchored map (&a). Merge that same alias repeatedly via <<: [a, a, ...]. Measure parse time and compare with control payload using single merge (<<: a). Observed repeated runs (same machine): K=M=1000, input 9,909 bytes: ~33–36 ms K=M=2000, input 20,909 bytes: ~121–123 ms K=M=4000, input 42,909 bytes: ~524–537 ms K=M=6000, input 64,909 bytes: ~1,608–1,829 ms K=M=8000, input 86,909 bytes: ~3,395–3,565 ms Control (single merge, similar key counts): K=2000: ~1–2 ms K=4000: ~3 ms K=8000: ~5 ms Also verified: repeated-merge output equals single-merge output (same key count and same JSON), confirming excess time is redundant computation.

Impact This is a denial-of-service vulnerability (CPU exhaustion / algorithmic complexity). Any service parsing untrusted YAML with js-yaml can be impacted, including API backends, CI tools, config processors, and automation services. An attacker can submit crafted YAML to significantly increase CPU time and reduce availability.

Suggested fix: Dedupe the merge source list by reference before invoking mergeMappings. Any of the following are minimal and preserve YAML 1.1 merge semantics:

dedupe in storeMappingPair:

if (keyTag === 'tag:yaml.org,2002:merge') { if (Array.isArray(valueNode)) { var seen = new Set(); for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { var src = valueNode[index]; if (seen.has(src)) continue; // idempotent; skip redundant alias seen.add(src); mergeMappings(state, result, src, overridableKeys); } } else { mergeMappings(state, result, valueNode, overridableKeys); } }

Other sources

js-yaml is a JavaScript YAML parser and dumper. Prior to 4.2.0 and 3.15.0, a crafted YAML document can trigger algorithmic CPU exhaustion in js-yaml merge-key processing (<<) by repeating the same alias many times in a merge sequence. This causes quadratic parse-time behavior relative to input size and can block a Node.js worker/event loop for seconds with a relatively small payload (tens of KB), resulting in denial of service. The issue is in merge handling inside lib/loader.js. This vulnerability is fixed in 4.2.0 and 3.15.0.

MITRE

Affected Software

3 affected componentsFixes available
npm/js-yaml<=4.1.1
4.2.0
Nodeca Js-yaml Node.js<3.15.0
Nodeca Js-yaml Node.js>=4.0.0<4.2.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/js-yaml to a version that resolves this vulnerability.

    Fixed in 4.2.0
  2. Upgrade

    Upgrade js-yaml to a version that resolves this vulnerability.

    Fixed in 4.2.0
  3. Upgrade

    Upgrade js-yaml to a version that resolves this vulnerability.

    Fixed in 3.15.0

Event History

Jun 15, 2026
Advisory Published
via GitHub·05:15 PM
Data Sourced
via GitHub·05:15 PM
DescriptionSeverityWeaknessAffected Software
Jun 22, 2026
CVE Published
via MITRE·02:59 PM
Data Sourced
via MITRE·02:59 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·04:16 PM
DescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the risk associated with CVE-2026-53550?

CVE-2026-53550 has a risk score of 27, indicating it is a medium severity vulnerability.

2

What is the impact of CVE-2026-53550?

CVE-2026-53550 can cause algorithmic CPU exhaustion due to poorly structured YAML files in the `js-yaml` library.

3

How can CVE-2026-53550 potentially affect application performance?

By triggering this vulnerability, it can block a Node.js worker or event loop for an extended period, leading to degraded application performance.

4

How do I mitigate CVE-2026-53550?

To mitigate CVE-2026-53550, avoid using repeated aliases in merge sequences within YAML documents processed by `js-yaml`.

5

What versions of `js-yaml` are affected by CVE-2026-53550?

While specific affected versions are not listed, it's advisable to review update notes and advisories related to `js-yaml` for applicable patches.

Contact

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