Skip to content

chore(deps): update dependency yaml to v2.8.3 [security] - #3902

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate-npm-yaml-vulnerability
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate-npm-yaml-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
yaml (source) 2.7.02.8.3 age confidence

yaml is vulnerable to Stack Overflow via deeply nested YAML collections

CVE-2026-33532 / GHSA-48c2-rrv3-qjmp

More information

Details

Parsing a YAML document with yaml may throw a RangeError due to a stack overflow.

The node resolution/composition phase uses recursive function calls without a depth bound. An attacker who can supply YAML for parsing can trigger a RangeError: Maximum call stack size exceeded with a small payload (~2–10 KB). The RangeError is not a YAMLParseError, so applications that only catch YAML-specific errors will encounter an unexpected exception type. Depending on the host application's exception handling, this can fail requests or terminate the Node.js process.

Flow sequences allow deep nesting with minimal bytes (2 bytes per level: one [ and one ]). On the default Node.js stack, approximately 1,000–5,000 levels of nesting (2–10 KB input) exhaust the call stack. The exact threshold is environment-dependent (Node.js version, stack size, call stack depth at invocation).

Note: the library's Parser (CST phase) uses a stack-based iterative approach and is not affected. Only the compose/resolve phase uses actual call-stack recursion.

All three public parsing APIs are affected: YAML.parse(), YAML.parseDocument(), and YAML.parseAllDocuments().

PoC
const YAML = require('yaml');

// ~10 KB payload: 5000 levels of nested flow sequences
const payload = '['.repeat(5000) + '1' + ']'.repeat(5000);

try {
  YAML.parse(payload);
} catch (e) {
  console.log(e.constructor.name); // RangeError (NOT YAMLParseError)
  console.log(e.message);          // Maximum call stack size exceeded
}

Test environment: Node.js v24.12.0, macOS darwin arm64

Version Nesting Depth Input Size Result
1.0.0 5,000 10,001 B RangeError
1.10.2 5,000 10,001 B RangeError
2.0.0 5,000 10,001 B RangeError
2.8.2 5,000 10,001 B RangeError
2.8.3 5,000 10,001 B YAMLParseError

Depth threshold on yaml 2.8.2:

Nesting Depth Input Size Result
500 1,001 B Parses successfully
1,000 2,001 B RangeError (threshold varies by stack size)
5,000 10,001 B RangeError

Severity

  • CVSS Score: 4.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

eemeli/yaml (yaml)

v2.8.3

Compare Source

  • Add trailingComma ToString option for multiline flow formatting (#​670)
  • Catch stack overflow during node composition (1e84ebb)

v2.8.2

Compare Source

  • Serialize -0 as -0 (#​638)
  • Do not double newlines for empty map values (#​642)

v2.8.1

Compare Source

  • Preserve empty block literals (#​634)

v2.8.0

Compare Source

  • Add node cache for faster alias resolution (#​612)
  • Re-introduce compatibility with Node.js 14.6 (#​614)
  • Add --merge option to CLI tool (#​611)
  • Improve error for tag resolution error on null value (#​616)
  • Allow empty string as plain scalar representation, for failsafe schema (#​616)
  • docs: include cli example (#​617)

v2.7.1

Compare Source

  • Do not allow seq with single-line collection value on same line with map key (#​603)
  • Improve warning & avoid TypeError on bad YAML 1.1 nodes (#​610)

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependencies Pull requests that update a dependency label Apr 15, 2026
@netlify

netlify Bot commented Apr 15, 2026

Copy link
Copy Markdown

Deploy Preview for brilliant-pasca-3e80ec canceled.

Name Link
🔨 Latest commit c07ae87
🔍 Latest deploy log https://app.netlify.com/projects/brilliant-pasca-3e80ec/deploys/6a5c08965367b1000887b048

@github-actions

github-actions Bot commented Apr 15, 2026

Copy link
Copy Markdown

🚀 Performance Test Results

Test Configuration:

  • VUs: 4
  • Duration: 1m0s

Test Metrics:

  • Requests/s: 57.61
  • Iterations/s: 19.22
  • Failed Requests: 0.00% (0 of 3465)
📜 Logs

> performance@1.0.0 run-tests:testenv /home/runner/work/rafiki/rafiki/test/performance
> ./scripts/run-tests.sh -e test -k -q --vus 4 --duration 1m

Cloud Nine GraphQL API is up: http://localhost:3101/graphql
Cloud Nine Wallet Address is up: http://localhost:3100/
Happy Life Bank Address is up: http://localhost:4100/
cloud-nine-wallet-test-backend already set
cloud-nine-wallet-test-auth already set
happy-life-bank-test-backend already set
happy-life-bank-test-auth already set
     data_received..................: 1.3 MB 21 kB/s
     data_sent......................: 2.7 MB 44 kB/s
     http_req_blocked...............: avg=6.31µs   min=1.4µs    med=4.27µs  max=875.48µs p(90)=5.69µs   p(95)=6.32µs  
     http_req_connecting............: avg=803ns    min=0s       med=0s      max=811.89µs p(90)=0s       p(95)=0s      
     http_req_duration..............: avg=68.95ms  min=6.33ms   med=54.5ms  max=414.27ms p(90)=115.66ms p(95)=132.1ms 
       { expected_response:true }...: avg=68.95ms  min=6.33ms   med=54.5ms  max=414.27ms p(90)=115.66ms p(95)=132.1ms 
     http_req_failed................: 0.00%  ✓ 0         ✗ 3465
     http_req_receiving.............: avg=78.22µs  min=21.62µs  med=67.65µs max=2.37ms   p(90)=98.04µs  p(95)=124.39µs
     http_req_sending...............: avg=29.02µs  min=6.97µs   med=20.98µs max=1.94ms   p(90)=32.18µs  p(95)=46.09µs 
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s      max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=68.84ms  min=6.23ms   med=54.41ms max=414.01ms p(90)=115.58ms p(95)=131.99ms
     http_reqs......................: 3465   57.608016/s
     iteration_duration.............: avg=208.01ms min=140.88ms med=195ms   max=812.2ms  p(90)=257.08ms p(95)=303.8ms 
     iterations.....................: 1156   19.219298/s
     vus............................: 4      min=4       max=4 
     vus_max........................: 4      min=4       max=4 

@renovate
renovate Bot force-pushed the renovate-npm-yaml-vulnerability branch from 1e5ee6f to 2a6c3ea Compare May 3, 2026 19:38
@mkurapov

mkurapov commented May 7, 2026

Copy link
Copy Markdown
Collaborator

@dependabot rebase

@renovate
renovate Bot force-pushed the renovate-npm-yaml-vulnerability branch from 2a6c3ea to c641ac4 Compare May 9, 2026 23:49
@renovate
renovate Bot force-pushed the renovate-npm-yaml-vulnerability branch 3 times, most recently from b10e870 to c271bfe Compare June 7, 2026 19:59
@renovate
renovate Bot force-pushed the renovate-npm-yaml-vulnerability branch from c271bfe to c07ae87 Compare July 18, 2026 23:13
mkurapov pushed a commit that referenced this pull request Sep 21, 2026
* chore(deps): bump @babel/core, protobufjs, yaml, webpack, tmp, tar, undici

Covers the seven security PRs that still need work: #3954, #3952, #3902,
#3826, #3953, #3867, #3849.

tmp is scoped to >=0.2.0 so the 0.0.33 copy under inquirer isn't dragged
across a major.

* chore(deps): bump handlebars, shell-quote, websocket-driver

Clears the last three critical advisories. All within-major.

* chore(deps): bump babel systemjs transform, devalue, fast-uri, flatted, postcss, svgo, next

Single-major highs, one override key each.

* chore(deps): range-scoped bumps for brace-expansion, immutable, js-yaml, minimatch, rollup, tar-fs, vite, ws

Each major line gets its own bounded key. Several of these packages have a
clean newer major in the tree (minimatch 10, tar-fs 3, rollup 4, vite 7.3.6)
that an unscoped override would have downgraded.

immutable 3.8.3 and vite 4.5.14 have no fix inside their own major, so they
stay. Listed in the PR description.

* chore(deps): astro 6.4.6, axios 1.18.0

Both are declared deps, so the package.json files move alongside the
override rather than drifting from it.

astro stays on ~6.4.x. Its remaining advisories only patch in 7.x, which
is a major and out of scope here.

* chore(deps): sharp 0.35.0, otel jaeger propagator 2.9.0

Both riskier than the rest. sharp ships native binaries so CI linux is the
real test, not local darwin.

The propagator override is scoped to 2.x. The 1.25.1 copy comes from
sdk-trace-node@1.25.1, which backend still pins on the otel v1 line;
moving that is an otel migration, not a dep bump.

* chore(deps): suppress propagator-jaeger advisory instead of an otel v2 migration

GHSA-45rx-2jwx-cxfr affects @opentelemetry/propagator-jaeger 1.25.1, which
comes in transitively via the backend's @opentelemetry/sdk-trace-node
^1.25.1. The only real fix is moving the backend's otel SDK deps
(resources, sdk-metrics, sdk-trace-node) to the v2 line, which drops
propagator-jaeger entirely.

I attempted that, plus the exporter realignment it needs (the backend
already has @opentelemetry/sdk-node@0.217.0 pulling in v2-era otlp-transformer
alongside the v1-era exporter-trace-otlp-grpc/exporter-metrics-otlp-grpc,
which crashes trace export outright due to clashing protobufjs globals).
Bumping the two grpc exporters to ^0.221.0 to match sdk-node "fixed" that
crash but traded it for a different one: v1's Span still has no
instrumentationScope field, which the v2-era serializer requires, so
export still fails, just with a different stack.

Decided not to chase the SDK v2 migration for this pass. Ignoring the GHSA
via pnpm.auditConfig.ignoreGhsas instead, so it's a stated, visible
suppression rather than a silently reverted fix. `pnpm audit` still lists
it, just tagged "(1 ignored)".

Separately: telemetry tracing looks broken on this branch (and likely
main) any time ENABLE_TELEMETRY_TRACES=true, independent of this GHSA -
the sdk-node bump in an earlier merged Renovate PR didn't realign the grpc
exporters, so trace export throws on the protobufjs global clash described
above. Nothing catches this today since service.test.ts mocks the otel
packages wholesale and CI never enables telemetry. Worth a separate look
by whoever owns telemetry.

* chore(deps): relay-compiler 13 to drop immutable 3

immutable 3.8.3 has two highs and no patched 3.x, so the only way out is to
move the thing that depends on it. relay-compiler 13.0.2 wants immutable ^5.1.9,
which the existing >=5.0.0 override already covers.

relay-operation-optimizer 7.0.0 asks for relay-compiler ^12, but its own latest
(7.1.8) asks for ^13.0.2 on the same optimizer major, so the API it uses didn't
move. Codegen output is unchanged.

Dropped the immutable@>=3.0.0 override since nothing wants immutable 3 now.

* chore(deps): vanilla-extract integration 8 to drop vite 4

vite 4.5.14 comes in under @vanilla-extract/integration 6.2.1 via remix's
classic compiler in mock-ASE. There's no vite this could upgrade to inside a
range 6.x accepts, and vite 5 is out of support so GHSA-fx2h has no 5.x patch.
integration v8 has no vite dependency at all, so vite just leaves.

v8 renamed createCompiler to compile and remix 2.17.5 still calls
createCompiler, but it's only reached from the .css.ts / .vanilla.css onLoad
handlers, and the plugin bails out earlier anyway unless the app declares
@vanilla-extract/css. mock-ASE does neither. This does become a landmine if
mock-ASE ever adopts vanilla-extract.

* chore(deps): unscope the tmp override to catch 0.0.33

external-editor is at its latest (3.1.0) and still pins tmp ^0.0.33, so the
>=0.2.0 selector never reached that copy. No upstream fix to wait for.

external-editor only calls tmp.tmpNameSync, which 0.2.7 still exports with the
same signature, and the path is inquirer's editor prompt inside graphql-codegen
which never runs interactively here. Forcing it across the 0.x major is the
only option that clears GHSA-ph9p-34f9-6g65.

* chore(deps): drop npm from the prod runner images

Every Grype and Trivy scan was failing on the same 5 highs plus a critical,
and none of them were ours. Trivy's paths gave it away: they all sit under
/usr/local/lib/node_modules/npm in the base image. node:24-alpine3.23 ships
npm 11.17.0, which bundles tar 7.5.16, brace-expansion 5.0.6, ip-address
10.2.0 and undici 6.26.0. I confirmed those versions by hand in the base
image and they match the scanner output exactly.

That's why the last few override bumps didn't move the needle. Our lockfile
already resolves tar 7.5.22 / brace-expansion 5.0.9 / undici 6.28.0, but a
pnpm override can't touch a copy of npm baked into the runner image.

The runner stages only ever exec node (frontend goes through
node_modules/.bin/remix-serve), corepack isn't enabled there, and nothing in
localenv or helm shells out to npm inside these containers, so npm is just
dead weight. Removing it takes out the whole class of finding rather than
this month's batch of it.

Built backend and frontend locally and scanned both tarballs: Trivy and Grype
both exit 0 at the high cutoff now, and npm no longer shows up anywhere in
the scanned path list. Grype passed even without .grype.yaml loaded, so it's
clean on its own rather than by suppression. I left the existing ignore rules
alone, though some of them may well be stale now.

* chore(deps): collapse propagator-jaeger onto v2

The backend image had one high left that was actually ours:
@opentelemetry/propagator-jaeger 1.25.1, CVE-2026-59892. The suppression I
added earlier only went into pnpm.auditConfig.ignoreGhsas, which covers
pnpm audit and nothing else, so Trivy kept failing on it.

Turns out this doesn't need the otel v2 migration I backed away from last
time. The backend already installs propagator-jaeger 2.10.0 via sdk-node
0.217.0, sitting right next to the 1.25.1 that sdk-trace-node 1.25.1 pulls
in. Both were already in the tree. So I widened the override, which was
scoped to @>=2.0.0 and therefore matched nothing, to just pin the package,
and the two collapse onto 2.10.0.

sdk-trace-node 1.x only ever constructs JaegerPropagator and registers it as
a TextMapPropagator, so the v1/v2 core split underneath doesn't matter here.
Checked it directly: NodeTracerProvider.register() with the v2 propagator
works, and an uber-trace-id round-trips through extract/inject with the trace
id, span id and flags intact. All 34 telemetry tests pass.

Only fixes the one CVE. @opentelemetry/core 1.22.0 and 1.25.1 are still in
there under GHSA-8988-4f7v-96qf, but that one's medium and below the scan
cutoff, and clearing it does need the SDK v2 move.

* chore(deps): record why bumping the base image doesn't help

Checked whether a newer tag would let us drop the npm removal. It won't.
Every node:24 alpine tag (3.22, 3.23, 3.24 and the floating 24-alpine) is
node 24.19.0 with npm 11.17.0 and the same bundled tar 7.5.16 /
brace-expansion 5.0.6 / ip-address 10.2.0.

Going further up doesn't fix it either. The newest published node image
(node:alpine, 26.7.0) ships npm 11.19.0, which is still brace-expansion 5.0.7
and ip-address 10.2.0. Both remain vulnerable to the highs that fail us:
GHSA-rgw5 wants 5.0.9, GHSA-mh99 wants 5.0.8, GHSA-mwp4 wants ip-address
10.3.1. So there's no base image at any node version that passes the high
cutoff right now, and we're on node 24 per engines anyway.

Just trimming the comment down and folding that finding into it, since it's
repeated in five files and it's what the next person will want to know.

* chore(deps): drop the scanner suppressions that are now dead

Three leftovers, none of which match anything anymore.

pnpm.auditConfig.ignoreGhsas held GHSA-45rx-2jwx-cxfr for propagator-jaeger
1.25.1. That version is gone from the tree since the override collapsed it
onto 2.10.0, so the entry can't match. pnpm audit reports the same 8 low and
23 moderate with it removed, and nothing tagged as ignored.

.grype.yaml and .trivyignore both carried CVE-2026-12151 (plus
GHSA-vxpw-j846-p89q on the grype side). Scanned all five prod images with no
ignore config at all, across every severity, and neither ID shows up. Running
grype with the config still loaded reports zero matches ignored, where CI was
logging 6 before, so what those rules were catching is fixed now.

Removed the files rather than leaving empty ones. Easy enough to re-add, and
#3947 set the precedent of pruning these as they get fixed.

All five images pass both scanners at CI's exact settings with the files gone.

* chore: fail docker if npm rm fail, rm npm doc references

* fix: openssl, next, faker, vulns

* fix: remove next

* fix: posgtres startup error on authed frontend

* fix: drop rollup and vite overrides that match nothing

---------

Co-authored-by: Blair Currey <12960453+BlairCurrey@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant