Skip to content

chore(deps): clear all critical + high npm advisories on development - #443

Merged
rubenvdlinde merged 2 commits into
developmentfrom
chore/dep-security-sweep
Aug 6, 2026
Merged

chore(deps): clear all critical + high npm advisories on development#443
rubenvdlinde merged 2 commits into
developmentfrom
chore/dep-security-sweep

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Measured state, not the reported count

The reported backlog was ~151 vulnerabilities (5 critical) for this repo. gh api .../dependabot/alerts?state=open returns 154 — but those are computed against the default branch main, which is 729 commits behind development and carries a completely different lockfile.

Measured directly against development:

ecosystem critical high moderate low total
composer (composer audit --locked) 0 0 0 0 0
npm (npm audit --package-lock-only) 1 2 5 5 13

The critical Dependabot flags for twig/twig etc. are already fixed on development (twig is at 3.27.0; the advisory range is < 3.26.0).

After this PR: 0 critical, 0 high, 3 moderate, 6 low.

Bumps

  • vitest 1.6.1 → 3.2.7 (+ @vitest/coverage-v8 to match) — clears the critical (Vitest UI server arbitrary file read/exec, <=3.2.5) and drags vite 5.4.21 → 7.3.6, vite-node → 3.2.4, esbuild 0.21.5 → 0.28.1, clearing the high and two moderates. npm audit proposed vitest@4; 3.2.7 is outside every advisory range and is one major less disruptive.
  • @cyclonedx/cyclonedx-npm 4.2.1 → 6.0.0 — clears the high (shell injection via unsanitised --workspace).
  • node-polyfill-webpack-plugin 3.0.0 → 4.1.0.

The interesting bit: a security override that broke the build

package.json carried a blanket overrides: { "minimatch": "^3.1.2" }, added to silence old minimatch advisories. It forces v3 on every consumer. test-exclude@7 (new, via coverage-v8 3.x) does const { minimatch } = require('minimatch') — the v10 named export — so v3's bare-function export destructured to undefined and npm run test:coverage died with TypeError: minimatch is not a function.

Dropping the blanket override lets each consumer resolve its own (test-exclude → 10.2.6, others → 9.0.9, root → 3.1.5). Nothing in the tree resolves below the 3.1.2 ReDoS fix — verified.

Verification

CI is node 20 / npm 10.8.2; local npm is 11, which prunes optional entries CI needs — so every lockfile operation here used npx npm@10.8.2.

  • npx npm@10.8.2 ci → rc=0, lockfile byte-identical afterwards. npm 11 ci --dry-run also rc=0.
  • vitest 210/210 pass · jest 120/120 pass
  • test:coverage rc=0; coverage ratchet rc=0 (vitest baseline is null/unseeded, so the 6.42% → 6.11% instrumentation shift cannot trip it)
  • npm run build → webpack compiled, 3 pre-existing warnings, 0 errors
  • npm run lint0 errors (355 pre-existing warnings, unchanged)
  • check:manifest, check:vue-demi, test:l10n → rc=0
  • Exact CI SBOM command under cyclonedx 6.0.0 → rc=0, valid CycloneDX specVersion 1.5, 814 components (CI runs npx @cyclonedx/cyclonedx-npm, which picks up the local devDependency — so the major bump is exercised)
  • Licences read from the lockfile, not the manifest: all bumps MIT except cyclonedx (Apache-2.0). vue3-apexcharts stays 1.8.0 MIT, pinned ~1.8.0 by @conduction/nextcloud-vue so it cannot drift into the proprietary 1.9.0 line. Untouched here.

Deliberately NOT fixed

dompurify (3 moderate) — would be a false green. @toast-ui/editor inlines DOMPurify 2.3.3 into its own dist and never require()s the dompurify package — confirmed by DOMPurify 2.3.3 appearing in js/softwarecatalog-main.js.LICENSE.txt. The flagged node_modules/@toast-ui/editor/node_modules/dompurify@2.5.9 is installed but never loaded. An npm overrides entry would turn the audit green and change nothing that ships. toast-ui 3.2.2 (latest) still depends on dompurify ^2.3.3, so there is no upstream fix. This needs real remediation (patch the dist, or replace the editor) — filed separately, not papered over here.

elliptic + 5 related lows — unreachable. They come in only via node-polyfill-webpack-plugin, whose plugin instance is discarded: webpack.config.js replaces the plugins array it inherits from @nextcloud/webpack-vue-config. No polyfill reaches the bundle (no elliptic in js/*.js). The package cannot simply be removed — @nextcloud/webpack-vue-config require()s it at module load without declaring it, so dropping it would break the build.

Measured state of `development` (npm audit --package-lock-only), NOT the
154 Dependabot alerts, which are computed against the DEFAULT branch `main`
— 729 commits behind and carrying a different lockfile entirely.

Before: 1 critical, 2 high, 5 moderate, 5 low (13). composer: 0.
After:  0 critical, 0 high, 3 moderate, 6 low (9).

Bumps
- vitest 1.6.1 -> 3.2.7 and @vitest/coverage-v8 to match.
  Clears the critical (Vitest UI server arbitrary file read/exec, <=3.2.5)
  and pulls vite 5.4.21 -> 7.3.6, vite-node -> 3.2.4, esbuild 0.21.5 -> 0.28.1,
  clearing the high (vite path traversal / fs.deny bypass) and two moderates.
  npm audit proposed vitest@4; 3.2.7 is outside every advisory range and is
  one major less disruptive.
- @cyclonedx/cyclonedx-npm 4.2.1 -> 6.0.0. Clears the high (shell injection
  via unsanitised --workspace). This repo passes no --workspace, so it was not
  reachable, but the SBOM step runs the local binary so the bump is exercised.
- node-polyfill-webpack-plugin 3.0.0 -> 4.1.0 (maintained line).

Drop the blanket `minimatch: ^3.1.2` override
That override existed to silence old minimatch advisories. It forced v3 on
EVERY consumer, and test-exclude@7 (new, via coverage-v8 3.x) does
`const { minimatch } = require('minimatch')` — the v10 named export — so v3's
bare-function export destructured to undefined and `npm run test:coverage`
died with "minimatch is not a function". Removing the override lets each
consumer resolve its own (test-exclude 10.2.6, others 9.0.9, root 3.1.5);
nothing in the tree resolves below the 3.1.2 ReDoS fix.

Verified (node 22 local; CI is node 20/npm 10.8.2)
- npx npm@10.8.2 ci: rc=0; lockfile byte-identical afterwards. npm 11 ci also ok.
- vitest 210/210 pass; jest 120/120 pass.
- test:coverage rc=0; ratchet rc=0 (vitest baseline is null/unseeded).
- npm run build: webpack compiled, 3 pre-existing warnings, 0 errors.
- npm run lint: 0 errors (355 pre-existing warnings, unchanged).
- check:manifest, check:vue-demi, test:l10n: rc=0.
- Exact CI SBOM command under cyclonedx 6.0.0: rc=0, valid CycloneDX
  specVersion 1.5, 814 components.
- Licences read from the LOCKFILE: all bumps MIT except cyclonedx (Apache-2.0).
  vue3-apexcharts stays 1.8.0 MIT, pinned ~1.8.0 by @conduction/nextcloud-vue,
  so it cannot drift into the proprietary 1.9.0 line. Untouched by this change.

NOT fixed here, deliberately
- dompurify (3 moderate): @toast-ui/editor INLINES DOMPurify 2.3.3 into its own
  dist and never require()s the dompurify package — confirmed in
  js/softwarecatalog-main.js.LICENSE.txt. The flagged
  node_modules/@toast-ui/editor/node_modules/dompurify@2.5.9 is installed but
  never loaded. An npm override would turn the audit green and change nothing
  that ships. toast-ui 3.2.2 (latest) still depends on dompurify ^2.3.3, so
  there is no upstream fix. Needs a real remediation, filed separately.
- elliptic/browserify-sign/create-ecdh/crypto-browserify/node-stdlib-browser
  (6 low): reachable only through node-polyfill-webpack-plugin, whose plugin
  instance is discarded — webpack.config.js REPLACES the plugins array from
  @nextcloud/webpack-vue-config. No polyfill lands in the bundle (no elliptic
  in js/*.js). The package cannot simply be dropped: webpack-vue-config
  require()s it at module load without declaring it.
OS command injection in PHP_CodeSniffer, GHSA-hmqg-cxww-wqhq, reported
2026-08-05. Affected: <3.13.6 | >=4.0.0,<4.0.2. This repo was on 3.13.5.

The advisory landed mid-review: this PR's own 'Security (composer)' leg PASSED
earlier today and the same leg on #445 then FAILED, on a config-only change.
The audit DB is live, so a composer.lock that was clean this morning is not
clean now — 'composer audit --locked' returned zero advisories for this repo
an hour before it returned this one.

Fleet-wide: all 16 checked repos are on 3.13.5 and are equally affected.

Verified
- composer audit --locked: 'No security vulnerability advisories found' (was 1).
- vendor/bin/phpcs --version -> 3.13.6.
- composer phpcs: rc=0, unchanged findings.
- Positive control: a deliberately non-conforming file under lib/ made phpcs
  exit 2 with 13 findings, so the green above is a real pass and not a checker
  that silently no-ops. Probe file removed; only composer.lock is modified.
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/softwarecatalog @ c107780

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue-demi
test-l10n
composer ✅ 121/121
npm ✅ 853/853
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-06 11:25 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/softwarecatalog @ 1f64c96

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue-demi
test-l10n
composer ✅ 121/121
npm ✅ 853/853
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-06 11:42 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 98a4612 into development Aug 6, 2026
29 checks passed
@rubenvdlinde
rubenvdlinde deleted the chore/dep-security-sweep branch August 6, 2026 11:45
@rubenvdlinde
rubenvdlinde restored the chore/dep-security-sweep branch August 8, 2026 16:18
@rubenvdlinde
rubenvdlinde deleted the chore/dep-security-sweep branch August 14, 2026 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant