@@ -12,17 +12,38 @@ const DEFAULT_DSN = 'https://username@domain/123';
1212const DEFAULT_SENTRY_ORG_SLUG = 'sentry-javascript-sdks';
1313const DEFAULT_SENTRY_PROJECT = 'sentry-javascript-e2e-tests';
1414
15- function asyncExec(command: string, options: { env: Record<string, string | undefined>; cwd: string }): Promise<void> {
15+ function asyncExec(
16+ command: string | string[],
17+ options: { env: Record<string, string | undefined>; cwd: string },
18+ ): Promise<void> {
1619 return new Promise((resolve, reject) => {
17- const process = spawn(command, { ...options, shell: true });
20+ // If command is an array, use spawn with separate command and args (safer)
21+ // If command is a string, maintain backward compatibility with shell: true
22+ let process: ReturnType<typeof spawn>;
23+ if (typeof command === 'string') {
24+ process = spawn(command, { ...options, shell: true });
25+ } else {
26+ if (command.length === 0) {
27+ return reject(new Error('Command array cannot be empty'));
28+ }
29+ const cmd = command[0];
30+ if (!cmd) {
31+ return reject(new Error('Command array cannot be empty'));
32+ }
33+ process = spawn(cmd, command.slice(1), { ...options, shell: false });
34+ }
1835
19- process.stdout.on('data', data => {
20- console.log(`${data}`);
21- });
36+ if (process.stdout) {
37+ process.stdout.on('data', data => {
38+ console.log(`${data}`);
39+ });
40+ }
2241
23- process.stderr.on('data', data => {
24- console.error(`${data}`);
25- });
42+ if (process.stderr) {
43+ process.stderr.on('data', data => {
44+ console.error(`${data}`);
45+ });
46+ }
2647
2748 process.on('error', error => {
2849 reject(error);
@@ -89,7 +110,8 @@ async function run(): Promise<void> {
89110 await asyncExec('volta run pnpm test:build', { env, cwd });
90111
91112 console.log(`Testing ${testAppPath}...`);
92- const testCommand = `volta run pnpm test:assert ${testFlags.join(' ')}`.trim();
113+ // Pass command and arguments as an array to prevent command injection
114+ const testCommand = ['volta', 'run', 'pnpm', 'test:assert', ...testFlags];
93115 await asyncExec(testCommand, { env, cwd });
94116
95117 // clean up (although this is tmp, still nice to do)
0 commit comments