Skip to content

fix(deps): patch dev-only security alerts in the root lockfile - #65

Merged
patrickbrandao merged 1 commit into
mainfrom
fix/54-dev-security-deps
Oct 11, 2026
Merged

patrickbrandao merged 1 commit into
mainfrom
fix/54-dev-security-deps

Conversation

@patrickbrandao

Copy link
Copy Markdown
Owner

Summary

PR B of #54: fixes the dev-only Dependabot alerts in the root package-lock.json with patch/minor updates only. It changes only the lockfile plus one override line. No majors, no .github/ changes, and the n8n node lockfile (#24) is untouched.

Package Before After Pulled in by Alerts closed
handlebars 4.7.9 4.7.10 ts-jest #96, #97 (critical), #98 (moderate)
fast-uri 3.1.6 3.1.8 ajv (root, @nestjs/cli, @nestjs/schematics) #61, #62 (high)
source-map-js 1.2.1 1.2.2 vite/postcss, jsdom (css-tree), magicast #91 (high)
undici 6 6.28.0 6.29.0 @codecov/vite-plugin (@actions/*) #75 (low)
undici 8 (jsdom copy) 8.10.0 (invalid) 8.11.2 jsdom 30.0.1 (^8.9.0) #67, #69 (high), #71, #77 (moderate), #68, #70, #76 (low)

That is 14 of the 15 open alerts on the root lockfile: 2 critical, 5 high, 3 moderate and 4 low. Dependabot closes them once this merges.

The undici override

The global override "undici": "^6.27.0" also applied to jsdom's undici 8 copy, so npm ls reported undici@8.10.0 invalid: "^6.27.0" from node_modules/jsdom. The override is now scoped to the 6.x line:

-    "undici": "^6.27.0",
+    "undici@^6": "^6.28.1",

npm only applies an override with a version-qualified key when the edge spec or node version matches that range. The @actions/* consumers (^6.23.0) keep a floor that is now the patched version, and jsdom resolves its own major. jsdom stays at 30.0.1, since it already accepts the patched undici 8. The lockfile was updated with npm update handlebars fast-uri source-map-js undici --package-lock-only, not a regeneration.

Not fixed: sprintf-js (#95, moderate, dev)

There is no fixed release. It comes in through js-yaml@3 → argparse@1, via @changesets/cli (read-yaml-file) and babel-plugin-istanbul (ts-jest). It goes away only with js-yaml 4, which depends on the Changesets major in v0.2. It remains an accepted dev-only risk, as triaged in #54.

Runtime image: unchanged

  • I replicated the prod-deps stage of docker/Dockerfile locally (npm ci --omit=dev --omit=optional --ignore-scripts with the root, shared, frontend and backend manifests) with the lockfile before and after this change. The installed trees are identical (332 name@version entries, empty diff).
  • None of handlebars, fast-uri, source-map-js, undici, jsdom or sprintf-js is in the prod tree.
  • npm ls --omit=dev --package-lock-only: the only differences are the dev/devOptional source-map-js and jsdom undici lines, and the ELSPROBLEMS error is gone.

Since runtime behavior does not change, this PR is opened ready for review, without a qa-docker run.

Verification

Gates (local, Node 26.9 / npm 11.19; CI runs Node 24)

Gate Result
npm ci ok
npm run lint ok (0 errors, 392 pre-existing warnings)
Build shared, backend (nest build), frontend (vite build), cli ok
Typecheck: cli (npm run typecheck), backend (tsc --noEmit with the workspace's TS 5.9.3), frontend (tsc --noEmit) ok
Unit shared 22 suites, 465 tests passed
Unit cli 14 suites, 325 tests passed
Unit backend 514 suites, 9697 tests passed
Unit frontend (TZ=UTC) 224 files, 4430 tests passed
Backend e2e, in band, disposable postgres:16, TZ=UTC, after migration:run 60 suites, 514 tests passed (container removed afterwards)

Two pre-existing issues, both unrelated to this change:

  • Frontend timezone test. Without TZ=UTC, one frontend test fails on a machine in America/Sao_Paulo: Account.test.tsx, "shows the scheduled cancellation access date for Pro users". It formats 2026-08-15T00:00:00Z in local time. CI runs in UTC, so it passes there. That test belongs to the billing UI being removed in refactor(frontend): remove the SaaS layer from the dashboard #51.
  • Backend typecheck with the root TypeScript. Running npx tsc -p packages/backend/tsconfig.json from the root picks up the hoisted TypeScript 6 and fails with TS5101 (baseUrl deprecated). The backend workspace's own TypeScript 5.9.3 typechecks cleanly. This belongs to the v0.2 TypeScript upgrade.

Refs #54

🤖 Generated with Claude Code

Lockfile-only patch/minor bumps for the dev-only alerts triaged in #54
(PR B). None of these packages is installed by the prod-deps image stage.

- handlebars 4.7.9 -> 4.7.10 (ts-jest)
- fast-uri 3.1.6 -> 3.1.8 (ajv)
- source-map-js 1.2.1 -> 1.2.2 (vite/postcss, jsdom)
- undici 6.28.0 -> 6.29.0 (@codecov/vite-plugin)
- undici 8.10.0 -> 8.11.2 (jsdom 30.0.1, which asks for ^8.9.0)

The global "undici": "^6.27.0" override also forced jsdom's undici 8 copy,
which npm ls reported as invalid. It is now scoped to the 6.x line
("undici@^6": "^6.28.1"), so jsdom resolves its own major and npm ls --all
is clean.

sprintf-js (#95) has no fixed release and stays until js-yaml 4 /
Changesets 3 in v0.2.

Refs #54

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@patrickbrandao

Copy link
Copy Markdown
Owner Author

Review of #65: fix(deps): patch dev-only security alerts in the root lockfile

Reviewed git diff origin/main...94af59e4ed01882086f20e314dfee8a5370ffcd9. The merge base is the current origin/main tip (94b7d38). The diff touches two files: package-lock.json (5 entries) and one override line in package.json.

Summary

Nothing is blocking. I found no should-fix items. The PR is not high risk: it changes no auth, crypto or key handling, adds no migration, does not touch tenant isolation, governance files, .github/ or releases, and adds no outbound destination.

1. Version bumps: patch/minor only

I checked each lockfile hunk. I also checked each resolved and integrity value against npm view <pkg>@<ver> dist.integrity, and they all match.

Entry Before After Bump Open alerts and first patched version
node_modules/fast-uri 3.1.6 3.1.8 patch #61, #62: 3.1.7
node_modules/handlebars 4.7.9 4.7.10 patch #96, #97, #98: 4.7.10
node_modules/jsdom/node_modules/undici 8.10.0 8.11.2 minor (same major as jsdom's ^8.9.0) #67-#71, #76, #77: 8.10.2
node_modules/source-map-js 1.2.1 1.2.2 patch #91: 1.2.2
node_modules/undici 6.28.0 6.29.0 minor #75: 6.28.1
  • The handlebars entry also changes its dependencies.minimist from ^1.2.5 to ^1.2.8. That is handlebars 4.7.10's own published manifest. The lockfile already resolves minimist@1.2.8, so nothing new is pulled in.
  • The engines fields are unchanged: undici 8 needs >=22.19.0 and undici 6 needs >=18.17, both as before.
  • I matched the alert list from the Dependabot API to the PR's claim: 14 of the 15 open alerts on package-lock.json are fixed (2 critical, 5 high, 3 moderate, 4 low). The remaining one is @solidjs/router 0.16 → 1.0 #95 (sprintf-js, no patched release), which is dev-only and was already triaged in Segurança: triagem dos 65 alertas do Dependabot herdados do upstream #54.

2. The undici override ("undici": "^6.27.0" changed to "undici@^6": "^6.28.1")

I read the matcher in the npm 11.19.1 arborist, @npmcli/arborist/lib/override-set.js.

  • Is the syntax valid? Yes. name@range keys are parsed into keySpec. getEdgeRule applies the rule only when the edge's raw spec semver.intersects the key range. getNodeRule uses semver.satisfies(node.version, keySpec).
  • Is the patched 6.x still forced? Yes. The three @actions/* edges (^6.23.0) intersect ^6, so they get ^6.28.1 and resolve to 6.29.0. The floor is now the first patched version for Pendências da chave THINKER_CATALOG_SYNC (#39) #75, where the old ^6.27.0 floor allowed vulnerable 6.27.x.
  • Is jsdom's 8.x left free? Yes. ^8.9.0 does not intersect ^6, so the override does not apply. npm ls --all --package-lock-only at the head exits 0 with undici@8.11.2. At the base it fails with ELSPROBLEMS (undici@8.10.0 invalid: "^6.27.0"). The old global override really was broken for jsdom, and this change fixes it.
  • Can a runtime consumer escape? No undici 6 consumer can. Any spec that intersects ^6 (*, >=5, 6.x, git ranges) is still overridden. Tag, file and directory specs always match. Only a future dependency declaring exactly ^5/^7 would escape, which is the intended scoping; Dependabot would flag it on its own line. Today the npm undici package has no runtime consumer at all (see the next section). The backend's mentions of undici (pricing-sync.service.ts, probe-error.ts, http-healing-client.ts) refer to Node's built-in fetch, which is bundled with the Node binary. Lockfile overrides don't affect it.

3. The runtime image is unchanged (confirmed)

I replicated the prod-deps stage of docker/Dockerfile for both base and head. I used the root, shared, frontend and backend manifests and ran npm ci --omit=dev --omit=optional --ignore-scripts. Both installs succeeded, and the name@version lists are identical (empty diff). No directory for undici, handlebars, fast-uri, source-map-js, jsdom, minimist or vitest exists in the prod node_modules.

One caveat on the spot-check you asked for: npm ls --omit=dev --package-lock-only <pkg> (even with --omit=optional) does list jsdom > undici@8.11.2 and source-map-js under manifest-frontend > better-auth > vitest. These come in through better-auth's optional peer on vitest, and all of them are flagged devOptional in the lockfile. npm ls displays them, but the real npm ci --omit=dev --omit=optional does not install them. The actual install is the authoritative check, and it confirms the claim in the PR.

The frontend dist is built by the full npm ci in the build stage, where source-map-js is present through vite/postcss. vite.config.ts doesn't enable build.sourcemap, so this patch bump has no effect on the shipped assets.

Conclusion: runtime behavior does not change, and a qa-docker run is not needed for this PR.

4. Tests and CI

  • Every check on 94af59e is success: Lint, Unit (shared/cli/backend/frontend), Backend e2e (PostgreSQL 16), Compose smoke test, install.sh end-to-end, CodeQL and dependency-review. CI mínima provisória #38's CI is on main, so CI is the gate. The local runs reported in the PR body are extra.
  • No new behavior needs tests. No changeset is needed, since nothing changes for users (dev-only lockfile).
  • The title is a Conventional Commit. The PR adds no manifest/mnfst identifiers; the root package name manifest is legacy and not touched here.

Findings

Blockers: none.

Should-fix: none.

Nits (informational, no action required):

  1. package.json:73: the scoped key undici@^6 intentionally stops covering other undici majors. If a dev or runtime dependency ever brings in undici 5.x or 7.x, the override won't put a floor on it. That is the right behavior, since forcing 6.x onto a ^7 consumer would break it. Leave the hardening of other majors to Dependabot rather than widening the override again.
  2. PR body, "Runtime image" section: say that npm ls --omit=dev still lists the devOptional peer chain (better-auth > vitest > jsdom), so a later reader doesn't take it for a regression. The npm ci tree comparison is the evidence that counts.

Head revisado: 94af59e
Veredito: aprovado

@patrickbrandao
patrickbrandao merged commit 8b5fce2 into main Oct 11, 2026
11 checks passed
@patrickbrandao
patrickbrandao deleted the fix/54-dev-security-deps branch October 11, 2026 04:06
patrickbrandao added a commit that referenced this pull request Oct 11, 2026
…le-selfhosted-mode

Brings in main (#5, #63, #69, #100, #103, #104, #106, #107 and the SaaS,
billing, Autofix and phone-home removals) through #66 and #70.

Resolutions:
- package-lock.json: keep undici 6.29.0 as a runtime dependency (no
  "dev": true), since ssrf-safe-fetch imports it; the version bump from
  #65 is kept.
- src/mcp/mcp-discovery.spec.ts: keep the single-mode test (canonical
  resource and issuer whatever the Host header) and serve it on loopback
  like the rest of the spec (#77).
- src/common/constants/local-servers.ts and its spec: import
  getContainerHostAlias from common/utils/container-host, since
  detect-self-hosted no longer exists.
- design-system/registry: regenerate (npm run design:registry). The
  Playground header classes from #106 were missing from it, which the
  pre-commit check refuses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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