mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-14 09:42:37 -04:00
fix(config): do not expand env vars in proxy fields from pnpm-workspace.yaml (#12871)
Project-level pnpm-workspace.yaml is repository-controlled and therefore
untrusted, so getOptionsFromPnpmSettings refuses to expand ${...}
environment-variable placeholders in request-destination fields. The guarded
set only covered registry, namedRegistries, and pnprServer; the httpProxy,
httpsProxy, and noProxy fields were missing, so a malicious repository could
route requests through an attacker-controlled proxy whose URL embedded a
secret and exfiltrate install-time secrets before any lifecycle script runs.
Add httpProxy, httpsProxy, and noProxy to REQUEST_DESTINATION_SCALAR_KEYS so
they receive the same protection already applied to the registry channel, and
extend the workspace-yaml request-destination test to cover them.
Reported by YESHYUNGSEOK as flaw F01 of GHSA-vx52-2968-3vc6.
This commit is contained in:
6
.changeset/proxy-fields-env-expansion.md
Normal file
6
.changeset/proxy-fields-env-expansion.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/config.reader": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`${...}` environment-variable placeholders in the `httpProxy`, `httpsProxy`, `noProxy`, `proxy`, and `noproxy` settings are no longer expanded when these settings come from a project's `pnpm-workspace.yaml`. They now receive the same protection already applied to `registry`, `namedRegistries`, and `pnprServer`.
|
||||
@@ -35,7 +35,7 @@ interface ReplaceEnvInSettingsOptions {
|
||||
expandRequestDestinationEnv: boolean
|
||||
}
|
||||
|
||||
const REQUEST_DESTINATION_SCALAR_KEYS = new Set(['pnprServer', 'registry'])
|
||||
const REQUEST_DESTINATION_SCALAR_KEYS = new Set(['pnprServer', 'registry', 'httpProxy', 'httpsProxy', 'noProxy', 'proxy', 'noproxy'])
|
||||
|
||||
export function getOptionsFromPnpmSettings (
|
||||
manifestDir: string | undefined,
|
||||
|
||||
@@ -936,6 +936,11 @@ test('pnpm-workspace.yaml request destinations do not expand env variables', asy
|
||||
|
||||
writeYamlFileSync('pnpm-workspace.yaml', {
|
||||
pnprServer: 'https://${PNPM_TEST_TOKEN}.evil.example/',
|
||||
httpsProxy: 'http://attacker.example/${PNPM_TEST_TOKEN}/',
|
||||
httpProxy: 'http://attacker.example/${PNPM_TEST_TOKEN}/',
|
||||
noProxy: '${PNPM_TEST_TOKEN}.example.com',
|
||||
proxy: 'http://attacker.example/${PNPM_TEST_TOKEN}/',
|
||||
noproxy: '${PNPM_TEST_TOKEN}.example.com',
|
||||
registries: {
|
||||
default: 'https://private.example.com/${PNPM_TEST_TOKEN}/',
|
||||
'@scope': 'https://scope.example.com/${PNPM_TEST_TOKEN}/',
|
||||
@@ -956,6 +961,9 @@ test('pnpm-workspace.yaml request destinations do not expand env variables', asy
|
||||
expect(config.registries['@scope']).toBeUndefined()
|
||||
expect(config.namedRegistries).toStrictEqual({})
|
||||
expect(config.pnprServer).toBeUndefined()
|
||||
expect(config.httpsProxy).toBeUndefined()
|
||||
expect(config.httpProxy).toBeUndefined()
|
||||
expect(config.noProxy).toBeUndefined()
|
||||
expect(JSON.stringify(config)).not.toContain('secret')
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user