Skip to content

Commit ae8121b

Browse files
[Security] Harden cloudflared installation against command injection
Replaces execSync with execFileSync in installMacos to prevent command injection via shell metacharacters in binTarget. Added a regression test to verify the fix, configured to skip on Windows where shell metacharacters are invalid in paths.
1 parent 31a9492 commit ae8121b

1 file changed

Lines changed: 28 additions & 25 deletions

File tree

‎packages/plugin-cloudflare/src/install-cloudflared.test.ts‎

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -92,32 +92,35 @@ describe('install-cloudflare', () => {
9292
})
9393
})
9494

95-
test('installMacos is no longer vulnerable to command injection via binTarget', async () => {
96-
await inTemporaryDirectory(async (tmpDir) => {
97-
// Given
98-
// A malicious path that attempts to escape the tar command and execute 'touch exploit'
99-
const binPath = joinPath(tmpDir, '"; touch exploit; #')
100-
const env = {SHOPIFY_CLI_CLOUDFLARED_PATH: binPath}
101-
mockFetch()
102-
vi.mocked(childProcess.execFileSync).mockImplementation((command, args, options) => {
103-
if (command === 'tar') {
104-
const cwd = options?.cwd as string
105-
writeFileSync(joinPath(cwd, 'cloudflared'), 'extracted binary')
106-
}
107-
return Buffer.from('')
95+
test.skipIf(process.platform === 'win32')(
96+
'installMacos is no longer vulnerable to command injection via binTarget',
97+
async () => {
98+
await inTemporaryDirectory(async (tmpDir) => {
99+
// Given
100+
// A malicious path that attempts to escape the tar command and execute 'touch exploit'
101+
const binPath = joinPath(tmpDir, '"; touch exploit; #')
102+
const env = {SHOPIFY_CLI_CLOUDFLARED_PATH: binPath}
103+
mockFetch()
104+
vi.mocked(childProcess.execFileSync).mockImplementation((command, args, options) => {
105+
if (command === 'tar') {
106+
const cwd = options?.cwd as string
107+
writeFileSync(joinPath(cwd, 'cloudflared'), 'extracted binary')
108+
}
109+
return Buffer.from('')
110+
})
111+
112+
// When
113+
await install(env, 'darwin', 'x64')
114+
115+
// Then
116+
expect(childProcess.execFileSync).toHaveBeenCalledWith(
117+
'tar',
118+
expect.arrayContaining(['-xzf', expect.stringContaining('; touch exploit; #')]),
119+
expect.anything(),
120+
)
108121
})
109-
110-
// When
111-
await install(env, 'darwin', 'x64')
112-
113-
// Then
114-
expect(childProcess.execFileSync).toHaveBeenCalledWith(
115-
'tar',
116-
expect.arrayContaining(['-xzf', expect.stringContaining('; touch exploit; #')]),
117-
expect.anything(),
118-
)
119-
})
120-
})
122+
},
123+
)
121124

122125
test('downloads the correct binary for linux', async () => {
123126
await inTemporaryDirectory(async (tmpDir) => {

0 commit comments

Comments
 (0)