Fix Command Injection in SvelteKit
Command Injection in SvelteKit manifests when server-side logic—specifically in +page.server.js or +server.js—passes unsanitized user input into Node.js child_process functions. If you use `exec()` with template literals, you're handing an attacker a shell. The fix is simple: stop spawning shells and start using argument arrays with `spawn()` or `execFile()` to ensure input is treated strictly as data.
The Vulnerable Pattern
import { exec } from 'child_process'; import { promisify } from 'util'; const execPromise = promisify(exec);/** @type {import(’./$types’).Actions} */ export const actions = { analyze: async ({ request }) => { const data = await request.formData(); const filename = data.get(‘filename’);
// VULNERABLE: String interpolation allows shell metacharacter injection (e.g., 'file.txt; rm -rf /') const { stdout } = await execPromise(`ls -l ./uploads/${filename}`); return { output: stdout }; }
};
The Secure Implementation
The vulnerability exists because `child_process.exec` invokes `/bin/sh` (or `cmd.exe`), interpreting special characters like `;`, `&`, and `|`. By switching to `execFile` or `spawn`, the command and its arguments are passed directly to the operating system's process creation API (like execve). This bypasses the shell interpreter entirely, rendering injection impossible because the input is never parsed for shell commands. Always combine this with a strict regex whitelist for input validation to minimize the attack surface further.
import { execFile } from 'child_process'; import { promisify } from 'util'; const execFilePromise = promisify(execFile);/** @type {import(’./$types’).Actions} */ export const actions = { analyze: async ({ request }) => { const data = await request.formData(); const filename = data.get(‘filename’);
// SECURE: Use execFile with an arguments array. No shell is spawned. // Also implement strict input validation as a second layer. if (!/^[a-zA-Z0-9._-]+$/.test(filename)) return { error: 'Invalid filename' }; try { const { stdout } = await execFilePromise('ls', ['-l', `./uploads/${filename}`]); return { output: stdout }; } catch (err) { return { error: 'Command failed' }; } }
};
Your SvelteKit API
might be exposed to Command Injection
74% of SvelteKit apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.