Update transitive js-yaml dependencies to 3.15.1 - #349
Merged
Mike Harder (mikeharder) merged 2 commits intoAug 18, 2026
Conversation
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix JS-YAML quadratic CPU consumption vulnerability
Update transitive js-yaml dependencies to 3.15.1
Aug 18, 2026
Mike Harder (mikeharder)
marked this pull request as ready for review
August 18, 2026 18:18
Mike Harder (mikeharder)
requested review from
Daniel Jurek (danieljurek) and
Ray Chen (raych1)
as code owners
August 18, 2026 18:18
Mike Harder (mikeharder)
enabled auto-merge (squash)
August 18, 2026 18:18
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
Ray Chen (raych1)
approved these changes
Aug 18, 2026
Mike Harder (mikeharder)
deleted the
copilot/fix-js-yaml-vulnerability-again
branch
August 18, 2026 18:26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
js-yaml3.15.0 is vulnerable to quadratic CPU consumption when resolving crafted!!omapinput, enabling denial of service.Dependency update
js-yamlresolutions from 3.15.0 to the lowest patched version, 3.15.1.js-yamlversion.Reachability assessment — high confidence
@azure/openapi-markdownand@ts-common/commonmark-to-markdown/front-matter.!!omapresolver.Original prompt
This section details the Dependabot vulnerability alert you should resolve
<alert_title>JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026-59870 fix not backported</alert_title>
<alert_description># Quadratic CPU consumption in
!!omapresolution (js-yaml 3.x and 4.x)Summary
resolveYamlOmap()enforces key uniqueness for!!omapsequences with a linearscan (
objectKeys.indexOf(...)) inside the per-element loop, making resolutionO(n²) in the number of entries. A modestly sized YAML document therefore
consumes disproportionate CPU inside
yaml.load(), giving a denial of serviceagainst any consumer that parses untrusted YAML.
!!omapis registered in the default schema(
lib/schema/default.js→require('../type/omap')), so a plainyaml.load(untrustedInput)with no options is affected — no custom schema ornon-default configuration is required.
This is the same weakness as CVE-2026-59870 / GHSA-724g-mxrg-4qvm, which was
fixed in the 5.x line in 5.2.1. That fix was never backported: both currently
maintained legacy lines still carry the original implementation.
Affected versions
objectKeys.indexOf(pairKey)atlib/type/omap.js:29objectKeys.indexOf(pairKey)atlib/type/omap.js:30Set)Both figures are the newest release of each line at the time of writing, so
this is not a "you are on an old version" issue.
Details
lib/type/omap.js(js-yaml 4.3.0):objectKeysgrows by one element per entry, andArray.prototype.indexOfis alinear scan, so resolving an
n-entry!!omapperforms roughly1 + 2 + … + ncomparisons — quadratic inn. The work happens synchronouslyinside
yaml.load(), blocking the event loop for its whole duration.The 5.x line already solves exactly this by tracking seen keys in a
Set(
src/tag/sequence/omap.ts):Proof of concept
Measured (node v20.20.2, default heap, no flags)
js-yaml 4.3.0
js-yaml 3.15.0
Runtime grows by a factor of ~4 for each doubling of
n, which is thesignature of O(n²) (linear growth would be ~2×).
Scaling further: a 2.48 MB document with 150,000 entries blocked
yaml.load()for 10.8 seconds.Impact
Any service that parses attacker-influenced YAML with js-yaml 3.x or 4.x can be
stalled with a small input. Because the loop is synchronous, a single request
blocks the Node.js event loop and stalls every other request in the process —
so the amplification is per-process, not just per-request.
Suggested severity: consistent with CVE-2026-59870 (the same weakness in
5.x), i.e. Availability-only impact, network attack vector, no privileges or
user interaction required.
Suggested fix
Mirror the 5.x fix — replace the linear scan with a
Set:This preserves the existing duplicate-key rejection semantics exactly while
making resolution O(n). A
maxOmapLength-style cap would also work, but theSetmatches what 5.x already ships and requires no new option.References
lib/type/omap.js(3.x, 4.x) — the affected resolverlib/schema/default.js— registers!!omapin the default schemaDiscovery
Found by an automated static-analysis and executed-proof-of-concept scanner run
against js-yaml 4.2.0, then manually verified against 3.15.0 and 4.3.0 by
executing the proof of concept above. All timings in this report were measured
on the current releases of each line, not on the version originally scanned.</alert_description>
high
GHSA-5p4m-2wfm-xmqj
js-yaml
npm
<vulnerable_versions>3.15.0</vulnerable_versions>
<patched_version>3.15.1</patched_version>
<manifest_path>package-lock.json</manife...