Repository navigation
fix(deps): resolve trivy high-severity vulnerabilities - #2616
Conversation
Remediate all HIGH findings from the Trivy scan by upgrading the affected (mostly transitive) dependencies via overrides, and adapt code to the breaking API changes those upgrades require. No behavioral changes beyond the library upgrades themselves; the full workspace build is green and tests pass for every modified package. CVE fixes (root package.json overrides): - brace-expansion CVE-2026-102276 / CVE-2026-102278 -> scoped "minimatch@10 > brace-expansion": ^5.0.12 (only the ESM 5.x copy is bumped; the CommonJS 1.x/2.x copies the CLI/oclif need are left intact) - pacote CVE-2026-9496 -> "yeoman-generator > pacote" and "lerna > pacote" ^21.5.1 - sigstore CVE-2026-48815 -> resolved via the pacote upgrade (pacote 21 pulls sigstore 4.x) - underscore CVE-2026-27601 -> underscore ^1.13.8 - yeoman-environment CVE-2026-42089 (arbitrary code execution) -> yeoman-environment ^6.0.1 - nodemailer -> ^10.0.6 (notification-service, pubnub-example, notification-socket-example, chat-notification examples) Code migrations required by the above upgrades: @sourceloop/cli (yeoman-environment 3 -> 6; stays CommonJS via Node require(esm), no ESM/oclif rewrite): - command-base.ts / commands/mcp.ts: Environment<T> -> Environment (v6 default export is non-generic); env.register(path, ns) -> register(path, {namespace}) - utilities/yeoman.ts: createEnv([], {cwd}, adapter) -> createEnv({cwd}) - utilities/mcp-adapter.ts: McpAdapter no longer extends TerminalAdapter (moved to the ESM-only @yeoman/adapter, not require-able from CJS); it now installs its prompt onto the environment's own adapter. Same fail-fast-on-prompt behavior. The removed-in-v6 Answers type is no longer imported. - .mocharc.json: preload yeoman-environment so mocha fully loads the ESM module before specs (avoids ERR_REQUIRE_ESM_RACE_CONDITION in the test harness) - test stubs: env.run's first argument is optional in v6 @sourceloop/observability (OpenTelemetry 1.x -> 2.x): - resources ^2.11.0, exporter-trace-otlp-grpc/http ^0.222.0, sdk-trace ^2.11.0 - otlp.profile.ts: new Resource() -> resourceFromAttributes(); detectResourcesSync() -> detectResources() (consolidated and synchronous in v2) sandbox/auth-public-private-client, sandbox/user-tenant-example (OTel 1.x -> 2.x): - sdk-trace-base/node ^2.11.0, exporter-jaeger ^2.11.0 (Jaeger exporter kept) - opentelemetry-registry.ts: provider.addSpanProcessor(...) -> new NodeTracerProvider({spanProcessors: [...]}) (addSpanProcessor removed in v2) @sourceloop/survey-service: - jsdom ^19 -> ^24 (restores w3c-hr-time, a transitive dropped during the lockfile regeneration; jsdom 24 no longer depends on it). JSDOM usage unchanged. Verification: - Trivy: 0 HIGH/CRITICAL findings - Full workspace build: passes - Tests: cli 22, observability 12, survey 134 passing - `sl scaffold` validated end-to-end on yeoman-environment 6 Note: installs must use --ignore-scripts (lavamoat preinstall-always-fail), followed by native-module builds (bcrypt, sqlite3) for native-dependent service tests to run. BREAKING CHANGE: yes. @sourceloop/cli now requires yeoman-environment 6 and Node >= 22.12 (it loads the ESM yeoman-environment via require(esm)), and @sourceloop/observability now targets the OpenTelemetry JS SDK 2.x (sdk-trace/resources 2.x, OTLP exporters 0.222). Consumers pinned to the previous majors must upgrade accordingly.
mocha 12 removed mocha/lib/utils, which mochawesome 7.1.4 requires, causing ERR_MOCHA_INVALID_REPORTER in the CI test jobs. Override mochawesome's mocha to ^11.8.0 so the reporter resolves a compatible mocha.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The Yeoman stack has unsupported dependency constraints and the CLI engine range does not enforce its stated Node 22.12 minimum.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Remediates high-severity dependency vulnerabilities and adapts CLI and tracing integrations for upgraded APIs.
Changes:
- Adds security overrides and upgrades Nodemailer, jsdom, Yeoman, and OpenTelemetry.
- Migrates Yeoman and OpenTelemetry API usage.
- Refreshes generated OpenAPI examples, tests, and lockfiles.
| File | Description |
|---|---|
package.json |
Adds vulnerability-remediation overrides. |
packages/cli/package.json |
Upgrades Yeoman environment. |
packages/cli/.mocharc.json |
Preloads Yeoman during tests. |
packages/cli/src/command-base.ts |
Migrates environment registration API. |
packages/cli/src/commands/mcp.ts |
Updates Environment typing. |
packages/cli/src/utilities/yeoman.ts |
Migrates environment creation and registration. |
packages/cli/src/utilities/mcp-adapter.ts |
Reworks noninteractive prompt handling. |
packages/cli/src/__tests__/commands/angular-scaffold.test.ts |
Updates run stub signature. |
packages/cli/src/__tests__/commands/react-scaffold.test.ts |
Updates run stub signature. |
packages/observability/package.json |
Upgrades OpenTelemetry SDK packages. |
packages/observability/src/profiles/otlp.profile.ts |
Migrates resource construction. |
services/notification-service/package.json |
Upgrades Nodemailer. |
services/survey-service/package.json |
Upgrades jsdom. |
services/survey-service/openapi.md |
Refreshes numeric examples. |
services/user-tenant-service/openapi.md |
Refreshes enum-like numeric examples. |
sandbox/auth-public-private-client/package.json |
Upgrades tracing packages. |
sandbox/auth-public-private-client/src/opentelemetry-registry.ts |
Migrates span processor setup. |
sandbox/user-tenant-example/package.json |
Upgrades tracing packages. |
sandbox/user-tenant-example/src/opentelemetry-registry.ts |
Migrates span processor setup. |
sandbox/pubnub-example/package.json |
Upgrades Nodemailer. |
sandbox/notification-socket-example/package.json |
Upgrades Nodemailer. |
sandbox/chat-notification-socketio-example/services/notifications-service/package.json |
Upgrades Nodemailer. |
sandbox/chat-notification-socketio-example/services/notifications-service/package-lock.json |
Locks upgraded dependencies. |
sandbox/chat-notification-socketio-example/services/chat-service/package-lock.json |
Refreshes transitive dependencies. |
sandbox/chat-notification-pubnub-example/services/notifications-service/package.json |
Upgrades Nodemailer. |
sandbox/chat-notification-pubnub-example/services/notifications-service/package-lock.json |
Locks upgraded dependencies. |
Files not reviewed (3)
- sandbox/chat-notification-pubnub-example/services/notifications-service/package-lock.json: Generated file
- sandbox/chat-notification-socketio-example/services/chat-service/package-lock.json: Generated file
- sandbox/chat-notification-socketio-example/services/notifications-service/package-lock.json: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| }, | ||
| "js-yaml": "^4.3.2", | ||
| "tmp": "^0.2.7", | ||
| "yeoman-environment": "^6.0.1", |
| "ts-morph": "^27.0.2", | ||
| "tslib": "^2.8.1", | ||
| "yeoman-environment": "^3.19.3", | ||
| "yeoman-environment": "^6.0.1", |
… transitives The previous lockfile was generated in a churned working tree and dropped transitive deps (peek-readable, readable-web-to-node-stream, @microsoft/tsdoc), causing CI test jobs to fail on 'Cannot find module'. Regenerated from a pristine checkout: complete tree (no dangling deps), Trivy 0, mocha capped below 12. Full workspace build and lerna test pass.
b51a2f5 to
599ce9a
Compare
|
rohit-sourcefuse
left a comment
There was a problem hiding this comment.
Thanks Piyush, solid work getting Trivy to zero. I checked it: the root and sandbox lockfiles come out clean, sl scaffold and the MCP scaffold tool work on yeoman-environment 6, and the OTel 2 migration builds and runs.
A few things before this can merge (details and fixes inline):
- The root
yeoman-environmentoverride breakssl microservice,sl extensionandsl update(and their MCP tools). They crash on load withERR_PACKAGE_PATH_NOT_EXPORTED. CI doesn't catch it because the command tests stubEnvironment. enginesstill allows Node 22.0 to 22.11, where every command fails withERR_REQUIRE_ESM.- Release: the major bump depends on the
BREAKING CHANGE:footer surviving the squash. If the squash body is just the title, cli and observability go out as patches. If it keeps the commit messages, notification-service and survey-service also get a major for a devDependency and a jsdom bump. I'd split cli + observability into their own PR with a proper footer, for example:
fix(cli): move to yeoman-environment 6
BREAKING CHANGE: @sourceloop/cli now needs Node >=22.12 because yeoman-environment 6 is ESM only and is loaded with require().
and a similar line for observability ("now targets the OpenTelemetry JS SDK 2.x"). The rest can stay fix(deps).
Smaller ones:
- Dev deps: nx 22.7.12 brings in
brace-expansion5.0.8 andsmol-toml1.6.1 (both flagged HIGH with--include-dev-deps), and theminimatch@10scope doesn't reach them."brace-expansion@5": "^5.0.12"plus"nx": {"smol-toml": "^1.7.1"}would cover them.form-data4.0.4 is also still pinned underwiddershinsandpostman-request; 4.0.6 has the fix. - Root overrides aren't published, so people installing
@sourceloop/clifrom npm still get the oldyeoman-environmentandpacote. Worth saying in the description that this fixes the repo scan. - The
overridesblock inpackages/cli/package.jsonis ignored by npm and can go. - The
openapi.mdchanges are regeneration noise (openapi-sampler bump), and the "mocha capped below 12" override was removed in the last commit, so either add it back or update the message. - A small test that loads the microservice generator with a real env (no stub) would have caught item 1.
| }, | ||
| "js-yaml": "^4.3.2", | ||
| "tmp": "^0.2.7", | ||
| "yeoman-environment": "^6.0.1", |
There was a problem hiding this comment.
This override also forces v6 onto @loopback/cli (it asks for ^3.19.3), and the lockfile now has only yeoman-environment@6.3.0. @loopback/cli/lib/utils.js line 22 does require('yeoman-environment/conflicter') at load time, and v6 only exports . and ./package.json. Our app-generator, extension-generator and update-generator import LoopBack's generators, so:
$ sl microservice my-facade --facade --uniquePrefix demo
Error: Package subpath './conflicter' is not defined by "exports" in .../node_modules/yeoman-environment/package.json
Code: ERR_PACKAGE_PATH_NOT_EXPORTED
The same happens for sl extension, sl update and the Microservice MCP tool. On master the same command creates the facade.
packages/cli already depends on yeoman-environment ^6.0.1 itself, so I think this line can just be removed:
"yeoman-environment": "^6.0.1",Without it npm nests v6 under the CLI, and @loopback/cli and yeoman-generator (peer ^3.2.0) keep their own v3. That leaves the v3 CVE on the @loopback/cli path until LoopBack supports v6, so it's worth a scoped .trivyignore entry or a note in the PR.
| "ts-morph": "^27.0.2", | ||
| "tslib": "^2.8.1", | ||
| "yeoman-environment": "^3.19.3", | ||
| "yeoman-environment": "^6.0.1", |
There was a problem hiding this comment.
Since yeoman-environment 6 is ESM only and is loaded through require(), the CLI now needs Node 22.12 or later. engines (line 19) still says "22 || 24". On Node 22.11, sl scaffold and sl mcp both fail straight away with ERR_REQUIRE_ESM from command-base.ts.
"engines": {
"node": "^22.12.0 || 24"
},CI uses the latest 22.x, so it won't show this.
| } | ||
|
|
||
| return detectResourcesSync().merge(new Resource(attributes)); | ||
| return detectResources().merge(resourceFromAttributes(attributes)); |
There was a problem hiding this comment.
OTel 2 changed this quietly. In 1.x the tracer provider merged the default resource into whatever you passed in. In 2.x TracerProvider does options.resource ?? defaultResource(), so passing a resource drops telemetry.sdk.language, telemetry.sdk.name and telemetry.sdk.version. Exported spans now only carry service name, version and environment.
import {
Resource,
defaultResource,
detectResources,
resourceFromAttributes,
} from '@opentelemetry/resources'; return defaultResource()
.merge(detectResources())
.merge(resourceFromAttributes(attributes));I checked that this brings the three attributes back on 2.11. A test that reads getFinishedSpans()[0].resource.attributes from the in-memory exporter would lock it in.
| "read-package-json": { | ||
| "glob": "^10.5.0" | ||
| }, | ||
| "js-yaml": "^4.3.2", |
There was a problem hiding this comment.
This one is new and unscoped, so it also forces v4 onto @oclif/core (v1 and v2 both ask for js-yaml ^3.14.1), and their table output calls yaml.safeDump, which v4 removed. Scoping it to the copies that were actually flagged keeps the fix without touching oclif:
"js-yaml@4": "^4.3.2",




Summary
Remediates all HIGH findings from the Trivy scan by upgrading the affected (mostly transitive) dependencies via
overrides, and adapts code to the breaking API changes those upgrades require. No behavioral changes beyond the library upgrades themselves — the full workspace build is green and tests pass for every modified package.BREAKING CHANGE:
yes
Vulnerabilities fixed
"minimatch@10": { "brace-expansion": "^5.0.12" }— only the ESM 5.x copy is bumped; the CommonJS 1.x/2.x copies the CLI/oclif need are left intactyeoman-generator > pacote+lerna > pacote^21.5.1underscore ^1.13.8yeoman-environment ^6.0.1^10.0.6in notification-service + pubnub / notification-socket / chat-notification examplesCode changes required by the upgrades
@sourceloop/cli— yeoman-environment 3 → 6 (stays CommonJS via Noderequire(esm); no ESM/oclif rewrite, CLI engines arenode 22 || 24):Environment<T>→Environment(the v6 default export is non-generic)env.register(path, ns)→register(path, { namespace })createEnv([], { cwd }, adapter)→createEnv({ cwd })McpAdapterno longerextends TerminalAdapter(that class moved to the ESM-only@yeoman/adapter, which cannot berequire()d from this CommonJS package —ERR_PACKAGE_PATH_NOT_EXPORTED). It now exposesinstall(env)that overridesenv.adapter.prompt. Same fail-fast-on-prompt behavior. TheAnswerstype (removed in v6) is no longer imported..mocharc.jsonpreloadsyeoman-environmentso mocha fully loads the ESM module before specs, avoidingERR_REQUIRE_ESM_RACE_CONDITIONin the test harness.env.run's first argument is optional in v6.@sourceloop/observability— OpenTelemetry 1.x → 2.x:resources/sdk-trace^2.11.0, OTLP exporters^0.222.0new Resource()→resourceFromAttributes();detectResourcesSync()→detectResources()(consolidated and synchronous in v2)sandbox/auth-public-private-client,sandbox/user-tenant-example— OpenTelemetry 1.x → 2.x:sdk-trace-base/node^2.11.0,exporter-jaeger ^2.11.0(Jaeger exporter kept — it has a 2.x release)provider.addSpanProcessor(...)→new NodeTracerProvider({ spanProcessors: [...] })(addSpanProcessorremoved in v2)@sourceloop/survey-service:jsdom ^19 → ^24(restoresw3c-hr-time, a transitive dropped during the lockfile regeneration; jsdom 24 no longer depends on it).JSDOMusage unchanged.Breaking changes
@sourceloop/clinow requires yeoman-environment 6 and Node >= 22.12 (it loads the ESMyeoman-environmentviarequire(esm)).@sourceloop/observabilitynow targets the OpenTelemetry JS SDK 2.x (sdk-trace/resources2.x, OTLP exporters 0.222).Consumers pinned to the previous majors must upgrade accordingly.
Verification
sl scaffoldvalidated end-to-end on yeoman-environment 6Notes for reviewers / CI
Installs must use
--ignore-scripts(lavamoatpreinstall-always-fail), followed by native-module builds (npm rebuild bcrypt sqlite3) for the native-dependent service tests to run.