fix(deps): patch transitive runtime CVEs via pnpm overrides

Closes 13 runtime-scope Dependabot advisories that Dependabot itself
cannot fix: the vulnerable packages are all transitive, so the bot has no
lever until each parent publishes a release widening its own pin.

Overrides added (pinned-source form, matching existing convention):

- @xmldom/xmldom 0.8.11 -> 0.8.13  (5 high) via video.js -> mpd-parser
- fast-uri       3.1.0  -> 3.1.4   (4 high) via electron-conf -> ajv
- js-yaml        4.1.1  -> 4.3.0   (2)      via electron-updater
- form-data      4.0.5  -> 4.0.6   (1 high) via axios
- ajv            8.17.1 -> 8.18.0  (1)      via electron-conf

Every target stays inside its parent's declared semver range. For xmldom,
fast-uri and js-yaml the newest published version is *outside* that range
(0.9.x / 4.x / 5.x), so "latest" would have broken them - the new doc
records that constraint.

Deliberately excluded:

- axios and uuid are direct deps already covered by open Dependabot PRs
  (#1251 bumps axios 1.16.0 -> 1.18.1; #1252 covers uuid). Hand-bumping
  them here would only conflict on the lockfile.
- undici (7 advisories) is labelled runtime scope but every path to it is
  build tooling - electron -> @electron/get, @angular/build, and
  @module-federation/dts-plugin. It is not in the packaged app.

Note on reachability: xmldom arrives via video.js -> VHS -> mpd-parser,
but the app routes every .mpd to Shaka, which uses its own DASH parser.
The code ships but is not on the playback path, so this is defence in
depth rather than closing a live hole. The genuinely reachable one is
js-yaml, which electron-updater uses to parse latest.yml from releases.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5 committed 2026-07-25 22:25:38 +02:00
1 parent 4e5132cbb5
commit d2316fafe9
3 files changed
+121 -52

No files matched your search

@@ -0,0 +1,66 @@
# Dependency Security Overrides
How transitive CVEs are patched in this repo, and the constraint that makes
"just bump to latest" the wrong move.
## Why overrides exist
Dependabot can only bump packages we declare ourselves. When the vulnerable
package is transitive — pulled in by `video.js`, `electron-updater`,
`electron-conf`, `axios` — the bot has no lever: it would have to wait for the
parent to publish a release that widens its own pin. Until then the alert stays
open regardless of how many bot PRs land.
`pnpm.overrides` in the root `package.json` is that lever. Every entry uses the
pinned-source form so an override only rewrites the exact resolution it was
written for, and goes stale visibly instead of silently re-targeting a future
version:
```json
"@xmldom/xmldom@0.8.11": "0.8.13"
```
## The semver ceiling
**An override must stay inside the range its parent declares.** pnpm applies
overrides without re-checking the parent's range, so an out-of-range target
installs cleanly and then fails at runtime or under load, not at install time.
For three of the five current security overrides, the newest published version
is _outside_ the parent's range. Taking "latest" would break them:
| Override | Pinned to | Parent range | Latest on npm |
| ---------------- | --------- | --------------------------------------- | ------------- |
| `@xmldom/xmldom` | 0.8.13 | `mpd-parser` `^0.8.3`, `plist` `^0.8.8` | 0.9.x ❌ |
| `fast-uri` | 3.1.4 | `ajv` `^3.0.1` | 4.x ❌ |
| `js-yaml` | 4.3.0 | `electron-updater` `^4.1.0` | 5.x ❌ |
| `form-data` | 4.0.6 | `axios` `^4.0.5` | 4.0.6 ✅ |
| `ajv` | 8.18.0 | `electron-conf` `^8.13.0` | 8.20.0 ✅ |
Before changing any of these, check the parent's declared range first:
```bash
npm view <parent>@<version> dependencies --json
```
## Verifying an override actually applied
pnpm leaves the superseded package block in `pnpm-lock.yaml` even when nothing
resolves to it any more, so grepping for the old version is misleading — it will
still be there. Check the _dependents_ instead, or resolve the real path on
disk:
```bash
node -e "console.log(require('./node_modules/.pnpm/mpd-parser@1.3.1/node_modules/@xmldom/xmldom/package.json').version)"
```
## What is deliberately not overridden
`undici` carries open alerts flagged `runtime` scope, but every path to it is
build tooling — `electron` → `@electron/get`, `@angular/build`, and
`@module-federation/dts-plugin`. It is not in the packaged app. The `runtime`
label is a Dependabot classification artifact, not a shipped-code claim. Bumping
it inside the Angular/Nx toolchain risks the build for no runtime benefit.
When triaging, confirm scope from the dependency graph rather than trusting the
alert's `scope` field.
+5
View File
@@ -217,16 +217,21 @@
"pnpm": {
"overrides": {
"@hono/node-server@1.19.9": "1.19.14",
"@xmldom/xmldom@0.8.11": "0.8.13",
"ajv@6.12.6": "6.14.0",
"ajv@8.17.1": "8.18.0",
"brace-expansion@1.1.12": "1.1.13",
"defu@6.1.4": "6.1.6",
"devalue@5.6.2": "5.6.4",
"express-rate-limit@8.2.1": "8.3.0",
"fast-uri@3.1.0": "3.1.4",
"flatted@3.3.3": "3.4.2",
"follow-redirects@1.15.11": "1.16.0",
"form-data@4.0.5": "4.0.6",
"h3@1.15.5": "1.15.10",
"hono@4.12.0": "4.12.14",
"immutable@5.1.4": "5.1.5",
"js-yaml@4.1.1": "4.3.0",
"lodash-es@4.17.22": "4.18.1",
"node-abi@3.85.0": "3.92.0",
"node-forge@1.3.3": "1.4.0",
+50 -52
View File
@@ -6,16 +6,21 @@ settings:
overrides:
'@hono/node-server@1.19.9': 1.19.14
'@xmldom/xmldom@0.8.11': 0.8.13
ajv@6.12.6: 6.14.0
ajv@8.17.1: 8.18.0
brace-expansion@1.1.12: 1.1.13
defu@6.1.4: 6.1.6
devalue@5.6.2: 5.6.4
express-rate-limit@8.2.1: 8.3.0
fast-uri@3.1.0: 3.1.4
flatted@3.3.3: 3.4.2
follow-redirects@1.15.11: 1.16.0
form-data@4.0.5: 4.0.6
h3@1.15.5: 1.15.10
hono@4.12.0: 4.12.14
immutable@5.1.4: 5.1.5
js-yaml@4.1.1: 4.3.0
lodash-es@4.17.22: 4.18.1
node-abi@3.85.0: 3.92.0
node-forge@1.3.3: 1.4.0
@@ -4712,10 +4717,9 @@ packages:
'@webassemblyjs/wast-printer@1.14.1':
resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==}
'@xmldom/xmldom@0.8.11':
resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
'@xmldom/xmldom@0.8.13':
resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==}
engines: {node: '>=10.0.0'}
deprecated: this version has critical issues, please update to the latest version
'@xtuc/ieee754@1.2.0':
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
@@ -4806,7 +4810,7 @@ packages:
ajv-formats@2.1.1:
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
peerDependencies:
ajv: ^8.0.0
ajv: 8.18.0
peerDependenciesMeta:
ajv:
optional: true
@@ -4814,7 +4818,7 @@ packages:
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
ajv: ^8.0.0
ajv: 8.18.0
peerDependenciesMeta:
ajv:
optional: true
@@ -4827,14 +4831,11 @@ packages:
ajv-keywords@5.1.0:
resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
peerDependencies:
ajv: ^8.8.2
ajv: 8.18.0
ajv@6.14.0:
resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==}
ajv@8.17.1:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
ajv@8.18.0:
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
@@ -6498,8 +6499,8 @@ packages:
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
fast-uri@3.1.0:
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
fast-uri@3.1.4:
resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==}
fastq@1.20.1:
resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
@@ -6620,8 +6621,8 @@ packages:
typescript: '>3.6.0'
webpack: ^5.11.0
form-data@4.0.5:
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
form-data@4.0.6:
resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==}
engines: {node: '>= 6'}
forwarded@0.2.0:
@@ -6871,6 +6872,10 @@ packages:
resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==}
engines: {node: '>= 0.4'}
hasown@2.0.4:
resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
engines: {node: '>= 0.4'}
hast-util-from-html@2.0.3:
resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
@@ -7608,8 +7613,8 @@ packages:
resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
hasBin: true
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
js-yaml@4.3.0:
resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==}
hasBin: true
jsdom@26.1.0:
@@ -11278,8 +11283,8 @@ snapshots:
'@angular-devkit/core@21.1.4(chokidar@5.0.0)':
dependencies:
ajv: 8.17.1
ajv-formats: 3.0.1(ajv@8.17.1)
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
jsonc-parser: 3.3.1
picomatch: 4.0.3
rxjs: 7.8.2
@@ -11595,7 +11600,7 @@ snapshots:
hast-util-from-html: 2.0.3
hast-util-to-text: 4.0.2
import-meta-resolve: 4.2.0
js-yaml: 4.1.1
js-yaml: 4.3.0
mdast-util-definitions: 6.0.0
rehype-raw: 7.0.0
rehype-stringify: 10.0.1
@@ -11621,7 +11626,7 @@ snapshots:
hast-util-from-html: 2.0.3
hast-util-to-text: 4.0.2
import-meta-resolve: 4.2.0
js-yaml: 4.1.1
js-yaml: 4.3.0
mdast-util-definitions: 6.0.0
rehype-raw: 7.0.0
rehype-stringify: 10.0.1
@@ -13272,7 +13277,7 @@ snapshots:
globals: 14.0.0
ignore: 5.3.2
import-fresh: 3.3.1
js-yaml: 4.1.1
js-yaml: 4.3.0
minimatch: 3.1.2
strip-json-comments: 3.1.1
transitivePeerDependencies:
@@ -16104,7 +16109,7 @@ snapshots:
'@webassemblyjs/ast': 1.14.1
'@xtuc/long': 4.2.2
'@xmldom/xmldom@0.8.11': {}
'@xmldom/xmldom@0.8.13': {}
'@xtuc/ieee754@1.2.0': {}
@@ -16190,10 +16195,6 @@ snapshots:
optionalDependencies:
ajv: 8.18.0
ajv-formats@3.0.1(ajv@8.17.1):
optionalDependencies:
ajv: 8.17.1
ajv-formats@3.0.1(ajv@8.18.0):
optionalDependencies:
ajv: 8.18.0
@@ -16214,17 +16215,10 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
ajv@8.17.1:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.1.0
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
ajv@8.18.0:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.1.0
fast-uri: 3.1.4
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
@@ -16335,7 +16329,7 @@ snapshots:
hosted-git-info: 4.1.0
is-ci: 3.0.1
isbinaryfile: 5.0.7
js-yaml: 4.1.1
js-yaml: 4.3.0
json5: 2.2.3
lazy-val: 1.0.5
minimatch: 10.1.1
@@ -16460,7 +16454,7 @@ snapshots:
html-escaper: 3.0.3
http-cache-semantics: 4.2.0
import-meta-resolve: 4.2.0
js-yaml: 4.1.1
js-yaml: 4.3.0
magic-string: 0.30.21
magicast: 0.5.2
mrmime: 2.0.1
@@ -16555,7 +16549,7 @@ snapshots:
axios@1.15.0:
dependencies:
follow-redirects: 1.16.0(debug@4.4.3)
form-data: 4.0.5
form-data: 4.0.6
proxy-from-env: 2.1.0
transitivePeerDependencies:
- debug
@@ -16563,7 +16557,7 @@ snapshots:
axios@1.16.0:
dependencies:
follow-redirects: 1.16.0(debug@4.4.3)
form-data: 4.0.5
form-data: 4.0.6
proxy-from-env: 2.1.0
transitivePeerDependencies:
- debug
@@ -16894,7 +16888,7 @@ snapshots:
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
is-ci: 3.0.1
js-yaml: 4.1.1
js-yaml: 4.3.0
sanitize-filename: 1.6.3
source-map-support: 0.5.21
stat-mode: 1.0.0
@@ -17269,7 +17263,7 @@ snapshots:
cosmiconfig@8.3.6(typescript@5.9.3):
dependencies:
import-fresh: 3.3.1
js-yaml: 4.1.1
js-yaml: 4.3.0
parse-json: 5.2.0
path-type: 4.0.0
optionalDependencies:
@@ -17279,7 +17273,7 @@ snapshots:
dependencies:
env-paths: 2.2.1
import-fresh: 3.3.1
js-yaml: 4.1.1
js-yaml: 4.3.0
parse-json: 5.2.0
optionalDependencies:
typescript: 5.9.3
@@ -17581,7 +17575,7 @@ snapshots:
builder-util-runtime: 9.3.1
fs-extra: 10.1.0
iconv-lite: 0.6.3
js-yaml: 4.1.1
js-yaml: 4.3.0
optionalDependencies:
dmg-license: 1.0.11
transitivePeerDependencies:
@@ -17702,7 +17696,7 @@ snapshots:
electron-conf@1.3.0(electron@41.7.2):
dependencies:
ajv: 8.17.1
ajv: 8.18.0
electron: 41.7.2
electron-playwright-helpers@1.8.2:
@@ -17715,7 +17709,7 @@ snapshots:
builder-util: 26.0.11
builder-util-runtime: 9.3.1
chalk: 4.1.2
form-data: 4.0.5
form-data: 4.0.6
fs-extra: 10.1.0
lazy-val: 1.0.5
mime: 2.6.0
@@ -17730,7 +17724,7 @@ snapshots:
dependencies:
builder-util-runtime: 9.7.0
fs-extra: 10.1.0
js-yaml: 4.1.1
js-yaml: 4.3.0
lazy-val: 1.0.5
lodash.escaperegexp: 4.1.2
lodash.isequal: 4.5.0
@@ -18379,7 +18373,7 @@ snapshots:
fast-levenshtein@2.0.6: {}
fast-uri@3.1.0: {}
fast-uri@3.1.4: {}
fastq@1.20.1:
dependencies:
@@ -18520,12 +18514,12 @@ snapshots:
typescript: 5.9.3
webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.18))(esbuild@0.28.1)
form-data@4.0.5:
form-data@4.0.6:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
es-set-tostringtag: 2.1.0
hasown: 2.0.3
hasown: 2.0.4
mime-types: 2.1.35
forwarded@0.2.0: {}
@@ -18806,6 +18800,10 @@ snapshots:
dependencies:
function-bind: 1.1.2
hasown@2.0.4:
dependencies:
function-bind: 1.1.2
hast-util-from-html@2.0.3:
dependencies:
'@types/hast': 3.0.4
@@ -19832,7 +19830,7 @@ snapshots:
argparse: 1.0.10
esprima: 4.0.1
js-yaml@4.1.1:
js-yaml@4.3.0:
dependencies:
argparse: 2.0.1
@@ -20786,14 +20784,14 @@ snapshots:
dependencies:
'@babel/runtime': 7.28.4
'@videojs/vhs-utils': 3.0.5
'@xmldom/xmldom': 0.8.11
'@xmldom/xmldom': 0.8.13
global: 4.4.0
mpd-parser@1.3.1:
dependencies:
'@babel/runtime': 7.28.4
'@videojs/vhs-utils': 4.1.1
'@xmldom/xmldom': 0.8.11
'@xmldom/xmldom': 0.8.13
global: 4.4.0
mpegts.js@1.8.0:
@@ -21098,7 +21096,7 @@ snapshots:
figures: 3.2.0
flat: 5.0.2
follow-redirects: 1.16.0(debug@4.4.3)
form-data: 4.0.5
form-data: 4.0.6
fs-constants: 1.0.0
function-bind: 1.1.2
get-caller-file: 2.0.5
@@ -21552,7 +21550,7 @@ snapshots:
plist@3.1.0:
dependencies:
'@xmldom/xmldom': 0.8.11
'@xmldom/xmldom': 0.8.13
base64-js: 1.5.1
xmlbuilder: 15.1.1