libnpmexec 10.2.9 → 10.3.0
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/lib/index.js +14 -5
- package/lib/run-script.js +3 -1
- package/lib/strict-allow-scripts-preflight.js +40 -0
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const { dirname, join, resolve } = require('node:path')
|
|
|
4
4
|
const crypto = require('node:crypto')
|
|
5
5
|
const { mkdir } = require('node:fs/promises')
|
|
6
6
|
const Arborist = require('@npmcli/arborist')
|
|
7
|
+
const strictAllowScriptsPreflight = require('./strict-allow-scripts-preflight.js')
|
|
7
8
|
const ciInfo = require('ci-info')
|
|
8
9
|
const { log, input } = require('proc-log')
|
|
9
10
|
const npa = require('npm-package-arg')
|
|
@@ -86,6 +87,9 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree, shallow })
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
// Strict-mode pre-flight for `npm exec` / `npx` lives in
|
|
91
|
+
// ./strict-allow-scripts-preflight.js
|
|
92
|
+
|
|
89
93
|
// see if the package.json at `path` has an entry that matches `cmd`
|
|
90
94
|
// the path is a known-local directory, not a user-supplied dep, so
|
|
91
95
|
// allow-directory must not gate this introspection
|
|
@@ -301,11 +305,16 @@ const exec = async (opts) => {
|
|
|
301
305
|
}
|
|
302
306
|
}
|
|
303
307
|
}
|
|
304
|
-
await withLock(lockPath, () =>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
add
|
|
308
|
-
|
|
308
|
+
await withLock(lockPath, async () => {
|
|
309
|
+
// Hard-fail before reify if --strict-allow-scripts is set and
|
|
310
|
+
// any node has install scripts not covered by allowScripts.
|
|
311
|
+
await strictAllowScriptsPreflight(npxArb, { ...flatOptions, add })
|
|
312
|
+
await npxArb.reify({
|
|
313
|
+
...flatOptions,
|
|
314
|
+
save: true,
|
|
315
|
+
add,
|
|
316
|
+
})
|
|
317
|
+
})
|
|
309
318
|
}
|
|
310
319
|
binPaths.push(resolve(installDir, 'node_modules/.bin'))
|
|
311
320
|
const pkgJson = await PackageJson.load(installDir)
|
package/lib/run-script.js
CHANGED
|
@@ -19,7 +19,9 @@ const run = async ({
|
|
|
19
19
|
// necessary for preventing bash/cmd keywords from overriding
|
|
20
20
|
if (!isWindowsShell) {
|
|
21
21
|
if (args.length > 0) {
|
|
22
|
-
|
|
22
|
+
// single-quote so shell metacharacters in the executable name are taken
|
|
23
|
+
// literally; double quotes still expand $(), backticks, $var and "
|
|
24
|
+
args[0] = `'${args[0].replace(/'/g, `'\\''`)}'`
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const { collectUnreviewedScripts, strictAllowScriptsError } = require('@npmcli/arborist/lib/unreviewed-scripts.js')
|
|
2
|
+
|
|
3
|
+
// Strict-mode pre-flight for `npm exec` / `npx`. When
|
|
4
|
+
// `--strict-allow-scripts` is set, build the npx-cache ideal tree and
|
|
5
|
+
// throw before reify if any node has install scripts not covered by
|
|
6
|
+
// the resolved `allowScripts` policy. The arborist gate already
|
|
7
|
+
// silently skips those scripts; this turns the silent skip into a
|
|
8
|
+
// hard failure for CI. Bypassed by `--ignore-scripts` and
|
|
9
|
+
// `--dangerously-allow-all-scripts`.
|
|
10
|
+
const strictAllowScriptsPreflight = async (arb, opts) => {
|
|
11
|
+
if (!opts.strictAllowScripts) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
if (opts.ignoreScripts || opts.dangerouslyAllowAllScripts) {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!arb.idealTree) {
|
|
19
|
+
await arb.buildIdealTree(opts)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const unreviewed = await collectUnreviewedScripts({
|
|
23
|
+
tree: arb.idealTree,
|
|
24
|
+
policy: opts.allowScripts || null,
|
|
25
|
+
ignoreScripts: opts.ignoreScripts,
|
|
26
|
+
dangerouslyAllowAllScripts: opts.dangerouslyAllowAllScripts,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
if (unreviewed.length === 0) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
throw strictAllowScriptsError(unreviewed, {
|
|
34
|
+
remediation:
|
|
35
|
+
'Pass --allow-scripts=<pkg> for one-off approval, or bypass this ' +
|
|
36
|
+
'check with --dangerously-allow-all-scripts.',
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = strictAllowScriptsPreflight
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libnpmexec",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.3.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"bin/",
|
|
6
6
|
"lib/"
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@gar/promise-retry": "^1.0.0",
|
|
64
|
-
"@npmcli/arborist": "^9.
|
|
64
|
+
"@npmcli/arborist": "^9.8.0",
|
|
65
65
|
"@npmcli/package-json": "^7.0.0",
|
|
66
66
|
"@npmcli/run-script": "^10.0.0",
|
|
67
67
|
"ci-info": "^4.0.0",
|