@pnpm/deps.security.signatures 1102.0.0 → 1102.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/lib/verifySignatures.d.ts +3 -1
- package/lib/verifySignatures.js +21 -9
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @pnpm/deps.security.signatures
|
|
2
2
|
|
|
3
|
+
## 1102.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `pnpm self-update`, `pnpm with`, and automatic package-manager version switching no longer wait through registry retry delays when a configured registry has no signatures and `registry.npmjs.org` is unavailable [#14483](https://github.com/pnpm/pnpm/issues/14483).
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @pnpm/error@1100.1.4
|
|
11
|
+
- @pnpm/network.fetch@1100.1.15
|
|
12
|
+
|
|
13
|
+
## 1102.0.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies:
|
|
18
|
+
- @pnpm/network.fetch@1100.1.14
|
|
19
|
+
|
|
3
20
|
## 1102.0.0
|
|
4
21
|
|
|
5
22
|
### Major Changes
|
|
@@ -104,7 +104,9 @@ export interface VerifyInstalledSignaturesOptions extends VerifySignaturesOption
|
|
|
104
104
|
* Signatures are verified against the caller's trusted keys over the installed
|
|
105
105
|
* integrity, so where the signature bytes come from does not affect what they
|
|
106
106
|
* prove — a package passes only when some genuine signature validates over the
|
|
107
|
-
* bytes actually installed.
|
|
107
|
+
* bytes actually installed. The fallback request is attempted once because it
|
|
108
|
+
* is an optional availability check after the primary registry already failed
|
|
109
|
+
* to provide a verifiable signature. See https://github.com/pnpm/pnpm/issues/13147.
|
|
108
110
|
*/
|
|
109
111
|
fallbackRegistry?: string;
|
|
110
112
|
}
|
package/lib/verifySignatures.js
CHANGED
|
@@ -16,7 +16,11 @@ export async function verifySignatures(packages, getAuthHeader, opts) {
|
|
|
16
16
|
};
|
|
17
17
|
// RegistriesByScope without signing keys are not counted as audited: there is no
|
|
18
18
|
// registry trust root to verify against.
|
|
19
|
-
const
|
|
19
|
+
const packumentContext = {
|
|
20
|
+
getAuthHeader,
|
|
21
|
+
opts,
|
|
22
|
+
packumentCache: new Map(),
|
|
23
|
+
};
|
|
20
24
|
const limit = pLimit(opts.networkConcurrency ?? 16);
|
|
21
25
|
await Promise.all(packages.map((pkg) => limit(async () => {
|
|
22
26
|
const keys = keysByRegistry.get(pkg.registry) ?? [];
|
|
@@ -25,7 +29,7 @@ export async function verifySignatures(packages, getAuthHeader, opts) {
|
|
|
25
29
|
let version;
|
|
26
30
|
let publishedAt;
|
|
27
31
|
try {
|
|
28
|
-
const packument = await getPackument(pkg,
|
|
32
|
+
const packument = await getPackument(pkg, packumentContext);
|
|
29
33
|
if (!packument)
|
|
30
34
|
return;
|
|
31
35
|
result.audited++;
|
|
@@ -107,13 +111,13 @@ async function fetchRegistryKeys(registry, getAuthHeader, opts) {
|
|
|
107
111
|
// attestations are intentionally handled separately from this registry check.
|
|
108
112
|
return body.keys.filter(({ keytype, scheme }) => keytype === 'ecdsa-sha2-nistp256' && scheme === 'ecdsa-sha2-nistp256');
|
|
109
113
|
}
|
|
110
|
-
async function getPackument(pkg,
|
|
111
|
-
const cacheKey = `${pkg.registry}:${pkg.name}`;
|
|
112
|
-
let packument = packumentCache.get(cacheKey);
|
|
114
|
+
async function getPackument(pkg, ctx) {
|
|
115
|
+
const cacheKey = `${ctx.cacheNamespace ?? ''}:${pkg.registry}:${pkg.name}`;
|
|
116
|
+
let packument = ctx.packumentCache.get(cacheKey);
|
|
113
117
|
if (!packument) {
|
|
114
118
|
// Multiple installed versions share one full packument fetch.
|
|
115
|
-
packument = fetchPackument(pkg, getAuthHeader, opts);
|
|
116
|
-
packumentCache.set(cacheKey, packument);
|
|
119
|
+
packument = fetchPackument(pkg, ctx.getAuthHeader, ctx.opts);
|
|
120
|
+
ctx.packumentCache.set(cacheKey, packument);
|
|
117
121
|
}
|
|
118
122
|
return packument;
|
|
119
123
|
}
|
|
@@ -267,6 +271,7 @@ export function getNpmSigningKeys() {
|
|
|
267
271
|
}
|
|
268
272
|
export async function verifyInstalledPackageSignatures(packages, trustedKeys, getAuthHeader, opts) {
|
|
269
273
|
const ctx = {
|
|
274
|
+
cacheNamespace: 'primary',
|
|
270
275
|
trustedKeys,
|
|
271
276
|
getAuthHeader,
|
|
272
277
|
opts,
|
|
@@ -301,7 +306,14 @@ async function findSignatureFailure(pkg, ctx) {
|
|
|
301
306
|
const { fallbackRegistry } = ctx.opts;
|
|
302
307
|
if (fallbackRegistry == null || equalRegistries(pkg.registry, fallbackRegistry))
|
|
303
308
|
return primary;
|
|
304
|
-
const secondary = await attemptSignatureVerification(pkg, fallbackRegistry,
|
|
309
|
+
const secondary = await attemptSignatureVerification(pkg, fallbackRegistry, {
|
|
310
|
+
...ctx,
|
|
311
|
+
cacheNamespace: 'fallback',
|
|
312
|
+
opts: {
|
|
313
|
+
...ctx.opts,
|
|
314
|
+
retry: { ...ctx.opts.retry, retries: 0 },
|
|
315
|
+
},
|
|
316
|
+
});
|
|
305
317
|
// A genuine signature validating over the installed integrity proves the
|
|
306
318
|
// installed bytes regardless of which registry the primary attempt hit or
|
|
307
319
|
// what it answered (e.g. a mirror serving stale signatures from a rotated
|
|
@@ -332,7 +344,7 @@ async function attemptSignatureVerification(pkg, registry, ctx) {
|
|
|
332
344
|
const displayRegistry = redactAndSanitize(registry);
|
|
333
345
|
let packument;
|
|
334
346
|
try {
|
|
335
|
-
packument = await getPackument({ ...pkg, registry }, ctx
|
|
347
|
+
packument = await getPackument({ ...pkg, registry }, ctx);
|
|
336
348
|
}
|
|
337
349
|
catch (err) {
|
|
338
350
|
// The fetch error may echo the request URL, credentials included.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/deps.security.signatures",
|
|
3
|
-
"version": "1102.0.
|
|
3
|
+
"version": "1102.0.2",
|
|
4
4
|
"description": "Verify package signatures from npm registries",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -29,17 +29,17 @@
|
|
|
29
29
|
"!*.map"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@pnpm/error": "1100.1.
|
|
32
|
+
"@pnpm/error": "1100.1.4",
|
|
33
33
|
"@pnpm/fetching.types": "1100.0.3",
|
|
34
|
-
"@pnpm/network.fetch": "1100.1.
|
|
35
|
-
"p-limit": "^7.3.
|
|
34
|
+
"@pnpm/network.fetch": "1100.1.15",
|
|
35
|
+
"p-limit": "^7.3.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@pnpm/logger": "^1100.0.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@jest/globals": "30.4.1",
|
|
42
|
-
"@pnpm/deps.security.signatures": "1102.0.
|
|
42
|
+
"@pnpm/deps.security.signatures": "1102.0.2",
|
|
43
43
|
"@pnpm/logger": "1100.0.0",
|
|
44
44
|
"@pnpm/testing.mock-agent": "1101.0.7"
|
|
45
45
|
},
|