diff --git a/.changeset/fierce-elks-leap.md b/.changeset/fierce-elks-leap.md new file mode 100644 index 000000000..9e1c2d979 --- /dev/null +++ b/.changeset/fierce-elks-leap.md @@ -0,0 +1,5 @@ +--- +type: Security +pr: 4565 +--- +**Patched a CPU-exhaustion issue in the vendored YAML parser (`js-yaml` 4.3.2)** — merge-key processing in YAML documents now counts empty mapping merges toward the existing `maxTotalMergeKeys` limit, closing a gap upstream backported from 5.4.1 (nodeca/js-yaml#797). diff --git a/gsd-core/bin/lib/vendor/js-yaml.cjs b/gsd-core/bin/lib/vendor/js-yaml.cjs index ba95c688b..fcd5aec7a 100644 --- a/gsd-core/bin/lib/vendor/js-yaml.cjs +++ b/gsd-core/bin/lib/vendor/js-yaml.cjs @@ -1262,16 +1262,21 @@ state.result += _result; } } + function chargeMergeWork(state) { + state.totalMergeKeys++; + if (state.maxTotalMergeKeys !== -1 && state.totalMergeKeys > state.maxTotalMergeKeys) { + throwError(state, "merge keys exceeded maxTotalMergeKeys (" + state.maxTotalMergeKeys + ")"); + } + } function mergeMappings(state, destination, source, overridableKeys) { if (!common2.isObject(source)) { throwError(state, "cannot merge mappings; the provided source object is unacceptable"); } + chargeMergeWork(state); var sourceKeys = Object.keys(source); for (var index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { var key = sourceKeys[index]; - if (state.maxTotalMergeKeys !== -1 && ++state.totalMergeKeys > state.maxTotalMergeKeys) { - throwError(state, "merge keys exceeded maxTotalMergeKeys (" + state.maxTotalMergeKeys + ")"); - } + chargeMergeWork(state); if (!_hasOwnProperty.call(destination, key)) { setProperty(destination, key, source[key]); overridableKeys[key] = true; @@ -1299,6 +1304,9 @@ } if (keyTag === "tag:yaml.org,2002:merge") { if (Array.isArray(valueNode)) { + if (valueNode.length > 100) { + throwError(state, "abnormal merge sequence size"); + } for (var _index = 0, _quantity = valueNode.length; _index < _quantity; _index += 1) { mergeMappings(state, _result, valueNode[_index], overridableKeys); } diff --git a/package-lock.json b/package-lock.json index 38a77f2a1..15a2f74e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3884,9 +3884,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index e3cc83000..da75abfa6 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "fast-check": "^4.8.0", "globals": "^16.5.0", "gpt-tokenizer": "4.0.0", - "js-yaml": "^4.3.1", + "js-yaml": "^4.3.2", "mutation-testing-metrics": "^3.7.3", "re2js": "^2.8.6", "typescript": "^6.0.3",