fix(config): avoid exporting persistent allow-scripts (#9913) · npm/cli@b016aa2 · GitHub
Skip to content

Commit b016aa2

Browse files
authored
fix(config): avoid exporting persistent allow-scripts (#9913)
## What / Why A user or global `.npmrc` can define `allow-scripts` as persistent policy. `setEnvs()` currently carries that non-default value into lifecycle child processes as `npm_config_allow_scripts`. If a lifecycle script runs a nested project-scoped `npm install`, the inner process treats the inherited value as an environment override and rejects it with `EALLOWSCRIPTS` instead of reloading the policy from its persistent config source. Mark `allow-scripts` as non-exportable. This only prevents `setEnvs()` from synthesizing the lifecycle environment variable; it does not remove an explicitly supplied environment value or change how the outer command reads its config. Pacote's git-preparation environment filtering and #9783 are outside this change. The regression test models a user-level value in the inherited config chain and verifies that lifecycle scripts do not receive `npm_config_allow_scripts`. ## AI assistance OpenAI Codex assisted with analysis, implementation, and test design. The patch was verified with the focused regression, the complete `@npmcli/config` suite, lint, and template checks. ## References Fixes #9912
1 parent 81a901c commit b016aa2

4 files changed

Lines changed: 54 additions & 1 deletion

File tree

‎tap-snapshots/test/lib/docs.js.test.cjs‎

Lines changed: 1 addition & 1 deletion

‎test/lib/utils/resolve-allow-scripts.js‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,22 @@ t.test('--allow-scripts CLI flag is rejected in project-scoped installs', async
8686
)
8787
})
8888

89+
t.test('allow-scripts environment policy is rejected in project-scoped installs', async t => {
90+
const mock = await mockNpm(t, {
91+
prefixDir: {
92+
'package.json': JSON.stringify({ name: 'p' }),
93+
},
94+
globals: {
95+
'process.env.npm_config_allow_scripts': 'canvas',
96+
},
97+
})
98+
const resolveAllowScripts = loadResolver(t)
99+
await t.rejects(
100+
resolveAllowScripts(mock.npm),
101+
{ code: 'EALLOWSCRIPTS', message: /--allow-scripts is not allowed/ }
102+
)
103+
})
104+
89105
t.test('--allow-scripts CLI flag is accepted in global installs (RFC layer 1 wins)', async t => {
90106
const mock = await mockNpm(t, {
91107
prefixDir: {

‎workspaces/config/lib/definitions/definitions.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ const definitions = {
271271
default: '',
272272
type: [String, Array],
273273
hint: '<package-list>',
274+
envExport: false,
274275
description: `
275276
Comma-separated list of packages whose install-time lifecycle scripts
276277
(\`preinstall\`, \`install\`, \`postinstall\`, and \`prepare\` for

‎workspaces/config/test/set-envs.js‎

Lines changed: 36 additions & 0 deletions

0 commit comments

Comments
 (0)