Skip to content

Commit 97da539

Browse files
authored
Merge pull request #1723 from input-output-hk/chore/dep-bumps
chore(deps): dependency modernization — WebdriverIO 9, express 5, resolutions →5
2 parents 38b158e + 7b8d487 commit 97da539

24 files changed

Lines changed: 4018 additions & 2371 deletions

File tree

.yarn/constraints.pro

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
1-
gen_enforced_dependency ForbidMaliciousReleases:
2-
backslash "!=0.2.1"
3-
chalk-template "!=1.1.1"
4-
supports-hyperlinks "!=4.1.1"
5-
has-ansi "!=6.0.1"
6-
simple-swizzle "!=0.2.3"
7-
color-string "!=2.1.1"
8-
error-ex "!=1.3.3"
9-
color-name "!=2.0.1"
10-
is-arrayish "!=0.3.3"
11-
slice-ansi "!=7.1.1"
12-
color-convert "!=3.1.1"
13-
wrap-ansi "!=9.0.1"
14-
ansi-regex "!=6.2.1"
15-
supports-color "!=10.2.1"
16-
strip-ansi "!=7.1.1"
17-
chalk "!=5.6.1"
18-
debug "!=4.4.2"
19-
ansi-styles "!=6.2.2"
1+
% Yarn constraints for supply-chain enforcement (`yarn constraints`).
2+
%
3+
% The Sept-2025 qix-hack malicious-version blocklist that previously lived
4+
% here has been removed: those releases are unpublished from npm (404) and
5+
% the affected packages now resolve to clean current versions, so the
6+
% blocklist no longer matches anything.
7+
%
8+
% Add `gen_enforced_dependency` rules below to block future malicious
9+
% releases or pin known-good versions, e.g.:
10+
%
11+
% gen_enforced_dependency ForbidMaliciousReleases:
12+
% some-package "!=1.2.3"

docs/security/dependency-vulnerability-audit-2026-06-19.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,59 @@ Moved only because an in-range relock re-resolved a shared sub-tree. Listed for
464464
| `webpack-sources` | 3.3.3 → 3.5.0 | transitive · dev-only · consumer:no | MIT | 7 / 3.5.0 |
465465
| `yargs` | 14.2.3, 16.2.0, 17.7.1 → 14.2.3, 16.2.0, 17.7.1, 17.7.3 | transitive · dev-only · consumer:no | MIT | 2 / 18.0.0 |
466466

467+
## Follow-up wave — direct bumps on the Node 22 baseline (2026-06-20)
468+
469+
The four deferred direct-dependency bumps that required the Node 22 runtime (or a major parent bump) as a prerequisite, now actioned together. Each clears a consumer-facing or build-context alert that the in-range relock could not reach; this resolves the interim PARTIAL on `uuid` from §A (its direct lines now all sit on the patched major; the residual `8.3.2`/`9.0.0` copies are transitive-only — pinned by `pg-boss`, `typeorm-extension` and the Trezor stack — and stay tracked).
470+
471+
| Package | Version (→ updated) | Status (severity) | Scope | License | Provenance / publisher |
472+
|---|---|---|---|---|---|
473+
| `uuid` | direct 10.0.0 → **11.1.1** (transitive 8.3.2, 9.0.0 remain) | CLOSED direct · PARTIAL transitive (medium) | direct · prod · consumer:yes | MIT | signed + SLSA; publisher `ctavan` → GitHub Actions OIDC (provenance adoption, benign) |
474+
| `ip-address` | 9.0.5 → **10.2.0** | CLOSED (medium) | direct · prod · consumer:yes | MIT | signed; publisher `beaugunderson` unchanged |
475+
| `axios` | 1.11.0 → **1.18.0** (in-range relock, ^1.7.4) | CLOSED (high) | direct · prod · consumer:yes | MIT | signed + SLSA; publisher `jasonsaayman` → GitHub Actions OIDC trusted-publisher (approver `jasonsaayman`), benign |
476+
| `express-openapi-validator` | 4.13.8 → **5.6.2** | CLOSED (high) | direct · prod · consumer:yes | MIT | signed; publisher `cdimascio` unchanged |
477+
| `multer` | 1.4.5-lts.2 → **2.2.0** | CLOSED (high) | transitive (via `express-openapi-validator`) · prod · consumer:yes | MIT | signed; publisher `linusu``ulisesgascon`**human→human**, a known maintenance handoff to the Express/OpenJS maintainer; benign |
478+
479+
### Dependencies modified in this wave
480+
481+
Only the direct `package.json` edges this PR touches: each arrow is a package whose manifest bumps the dependency it points to (sinks coloured by advisory severity — 🟡 medium · 🟠 high). `axios` is an in-range relock (same `^1.7.4` range, new resolution). Everything downstream inherits these transitively and is **not** itself modified, so it is not shown.
482+
483+
```mermaid
484+
flowchart LR
485+
classDef pkg fill:#eef2ff,stroke:#6366f1,color:#111;
486+
classDef med fill:#fde68a,stroke:#a16207,color:#111;
487+
classDef high fill:#fdba74,stroke:#c2410c,color:#111;
488+
489+
p_core["core"]:::pkg
490+
p_cardano_services["cardano-services"]:::pkg
491+
p_cardano_services_client["cardano-services-client"]:::pkg
492+
p_e2e["e2e"]:::pkg
493+
p_util_dev["util-dev"]:::pkg
494+
p_projection_typeorm["projection-typeorm"]:::pkg
495+
p_wallet["wallet"]:::pkg
496+
p_web_extension["web-extension"]:::pkg
497+
498+
d_ip("ip-address<br/>medium"):::med
499+
d_axios("axios<br/>high · relock"):::high
500+
d_eov("express-openapi-validator → multer<br/>high"):::high
501+
d_uuid("uuid<br/>medium"):::med
502+
503+
p_core --> d_ip
504+
p_cardano_services --> d_axios
505+
p_cardano_services --> d_eov
506+
p_cardano_services --> d_uuid
507+
p_cardano_services_client --> d_axios
508+
p_e2e --> d_axios
509+
p_e2e --> d_uuid
510+
p_util_dev --> d_axios
511+
p_projection_typeorm --> d_uuid
512+
p_wallet --> d_uuid
513+
p_web_extension --> d_uuid
514+
```
515+
516+
- **Cross-referenced databases:** OSV.dev returns **0** records for every resolved version above (`uuid@11.1.1`, `ip-address@10.2.0`, `axios@1.18.0`, `multer@2.2.0`, `express-openapi-validator@5.6.2`). **0** of the residual transitive advisories (`uuid<11.1.1`, `ws 8.5.0`, `yaml 2.6.1`) intersect the CISA KEV catalogue (1623 entries) — none are under active exploitation, so deferral remains appropriate.
517+
- **Production closure:** `yarn npm audit --environment production` is clean (exit 0) on this baseline — no advisory reaches a published package's production tree.
518+
- **Regression check:** lockfile diff vs the Node 22 baseline shows only upgrades and removals consistent with these bumps (e.g. `express-openapi-validator` v5 swaps `json-schema-ref-parser``@apidevtools/json-schema-ref-parser` 14.x, drops `lodash.uniq`/`lodash.zipobject`/`call-me-maybe`/`concat-stream@1.x`; `multer` 1.x removed). No shared transitive was silently downgraded.
519+
467520
## Method & limitations
468521

469522
- **Vulnerability status** tests each resolved version against the advisory's vulnerable range (semver). PARTIAL = the manifest range moved to a patched version but another consumer pins an older, still-vulnerable copy — enumerated in the deferred-work issues (#1701#1708).

package.json

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,17 @@
9090
"ts-node": "^10.0.0",
9191
"ts-node-dev": "^1.1.8",
9292
"tsc-alias": "^1.8.10",
93-
"tsx": "^4.15.6",
93+
"tsx": "^4.22.4",
9494
"typedoc": "^0.23.24",
9595
"typedoc-plugin-missing-exports": "^1.0.0",
9696
"typescript": "^4.7.4"
9797
},
9898
"packageManager": "yarn@3.2.1",
9999
"resolutions": {
100-
"color": "4.2.3",
101-
"color-string": "1.9.1",
102-
"color-convert": "2.0.1",
103-
"color-name": "1.1.4",
104-
"chalk": "4.1.2",
105-
"chalk-template": "1.1.0",
106-
"wrap-ansi": "7.0.0",
107-
"slice-ansi": "7.1.0",
108-
"strip-ansi": "6.0.1",
109-
"ansi-styles": "4.3.0",
110-
"ansi-regex": "5.0.1",
111-
"supports-color": "7.2.0",
112-
"supports-hyperlinks": "3.0.0",
113-
"debug": "4.3.4",
114-
"is-arrayish": "0.3.2",
115-
"simple-swizzle": "0.2.2",
116-
"error-ex": "1.3.2",
117-
"has-ansi": "5.0.1",
118-
"backslash": "0.2.0",
119-
"protobufjs": "7.6.4"
100+
"@opentelemetry/core": "^2.8.0",
101+
"js-yaml": "^4.2.0",
102+
"tar": "^7.5.16",
103+
"tmp": "^0.2.6",
104+
"uuid": "^11.1.1"
120105
}
121106
}

packages/cardano-services-client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"@types/validator": "^13.7.1",
4747
"axios-mock-adapter": "^2.0.0",
4848
"eslint": "^7.32.0",
49-
"express": "^4.20.0",
49+
"express": "^5.2.1",
5050
"get-port-please": "^2.5.0",
5151
"jest": "^28.1.3",
5252
"madge": "^5.0.1",

packages/cardano-services/package.json

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,16 @@
6565
"@types/cors": "^2.8.13",
6666
"@types/death": "^1.1.2",
6767
"@types/dockerode": "^3.3.8",
68-
"@types/express": "^4.17.13",
68+
"@types/express": "^5.0.6",
6969
"@types/express-prometheus-middleware": "^1.2.1",
7070
"@types/lodash": "^4.14.182",
7171
"@types/pg": "^8.6.5",
72-
"@types/uuid": "^8.3.4",
7372
"@types/wait-on": "^5.3.1",
7473
"@types/ws": "^8.5.10",
7574
"axios-mock-adapter": "^2.0.0",
7675
"cbor": "^8.1.0",
7776
"delay": "^5.0.0",
78-
"dockerode": "^3.3.1",
77+
"dockerode": "^4.0.7",
7978
"dockerode-utils": "^0.0.7",
8079
"eslint": "^7.32.0",
8180
"get-port-please": "^2.5.0",
@@ -88,7 +87,7 @@
8887
"ts-node": "^10.0.0",
8988
"typeorm-extension": "^2.7.0",
9089
"typescript": "^4.7.4",
91-
"wait-on": "^6.0.1"
90+
"wait-on": "^9.0.0"
9291
},
9392
"dependencies": {
9493
"@blockfrost/blockfrost-js": "^5.7.0",
@@ -104,7 +103,7 @@
104103
"axios": "^1.7.4",
105104
"backoff-rxjs": "^7.0.0",
106105
"bignumber.js": "^9.1.0",
107-
"body-parser": "^1.20.3",
106+
"body-parser": "^2.3.0",
108107
"bottleneck": "^2.19.5",
109108
"bunyan": "^1.8.15",
110109
"commander": "^9.1.0",
@@ -113,9 +112,9 @@
113112
"debug": "^4.3.4",
114113
"dotenv": "^16.0.0",
115114
"envalid": "^7.3.1",
116-
"express": "^4.20.0",
117-
"express-openapi-validator": "^4.13.8",
118-
"express-prom-bundle": "^6.4.1",
115+
"express": "^5.2.1",
116+
"express-openapi-validator": "^5.6.2",
117+
"express-prom-bundle": "^8.0.0",
119118
"fraction.js": "^4.2.0",
120119
"fuse.js": "^7.0.0",
121120
"json-bigint": "^1.0.0",
@@ -126,13 +125,13 @@
126125
"pg": "^8.7.3",
127126
"pg-boss": "8.4.2",
128127
"pg-connection-string": "^2.5.0",
129-
"prom-client": "^14.0.1",
128+
"prom-client": "^15.1.3",
130129
"reflect-metadata": "~0.1.13",
131130
"rxjs": "^7.4.0",
132131
"ts-custom-error": "^3.2.0",
133132
"ts-log": "^2.2.4",
134133
"typeorm": "^0.3.15",
135-
"uuid": "^10.0.0",
134+
"uuid": "^11.1.1",
136135
"ws": "^8.17.1"
137136
},
138137
"files": [

packages/cardano-services/src/Http/HttpServer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,10 @@ export class HttpServer extends RunnableModule {
275275
metricsPath: path
276276
.join(versionPath, this.#config.metrics?.options?.metricsPath || '/metrics')
277277
.replaceAll(path.sep, '/')
278-
})
278+
// express-prom-bundle v8 types Opts as a discriminated (summary|histogram) union;
279+
// spreading the optional config options into the literal can't be narrowed, so assert
280+
// the (runtime-valid, histogram) shape explicitly.
281+
} as expressPromBundle.Opts)
279282
);
280283
this.logger.info(
281284
`Prometheus metrics: ${(await promRegistry.getMetricsAsArray()).map(({ name }) => name)} configured at ${

packages/cardano-services/src/util/http.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ export const listenPromise = (
77
listenOptions: ListenOptions = {}
88
): Promise<http.Server> =>
99
new Promise((resolve, reject) => {
10-
const server = serverLike.listen(listenOptions, () => resolve(server)) as http.Server;
10+
// express 5's `app.listen` forwards bind errors to the listen callback (error-first),
11+
// whereas raw http.Server.listen signals them via the 'error' event — handle both so a
12+
// failed bind (e.g. EADDRINUSE) rejects instead of resolving with an unbound server.
13+
const server = serverLike.listen(listenOptions, (error?: Error) =>
14+
error ? reject(error) : resolve(server)
15+
) as http.Server;
1116
server.on('error', reject);
1217
});
1318

packages/cardano-services/src/util/openApi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { OpenAPIV3 } from 'express-openapi-validator/dist/framework/types';
22

33
export const versionPathFromSpec = (specPath: string) => {
44
try {
5-
const apiDoc = require(specPath) as OpenAPIV3.Document;
5+
const apiDoc = require(specPath) as OpenAPIV3.DocumentV3;
66

77
return `/v${apiDoc.info.version}`;
88
} catch (error) {

packages/cardano-services/test/Http/HttpServer.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ describe('HttpServer', () => {
184184
.filter(({ level, message }) => level === 'debug' && message[0] === '[HttpServer|request]')
185185
.map(({ message: [, requestDetails] }) => requestDetails)
186186
).toEqual([
187-
{ body: {}, method: 'HEAD', path: baseVersionPath, query: {} },
187+
// body-parser v2 leaves req.body undefined for bodyless requests (v1 set it to {})
188+
{ body: undefined, method: 'HEAD', path: baseVersionPath, query: {} },
188189
{
189190
body: { bigint: 23n, check: 'ok', test: 42 },
190191
method: 'POST',
@@ -193,7 +194,7 @@ describe('HttpServer', () => {
193194
query: {}
194195
},
195196
{
196-
body: {},
197+
body: undefined,
197198
method: 'GET',
198199
// Note: `.replaceAll(path.sep, '/')` is needed on Windows:
199200
path: path.join(someServiceVersionPath, 'stake-pool', 'echo').replaceAll(path.sep, '/'),

packages/cardano-services/test/util/openApi.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe('openApi utils', () => {
88
const apiSpecPath = path.join(__dirname, '..', '..', 'src', 'Http', 'openApi.json');
99
const {
1010
info: { version }
11-
} = require(apiSpecPath) as OpenAPIV3.Document;
11+
} = require(apiSpecPath) as OpenAPIV3.DocumentV3;
1212
expect(version).not.toBeUndefined();
1313
expect(versionPathFromSpec(apiSpecPath)).toBe(`/v${version}`);
1414
});

0 commit comments

Comments
 (0)