flawopen.com/Command Injection/exec vs execFile
exec() takes one string and runs it through a shell — shell features like pipes and wildcards work, but so does shell metacharacter injection. execFile() takes a program name and an argument array, with no shell involved at all — safer, but you lose shell features like pipes.
exec(`ls ${dir} | grep .txt`,
(err, out) => {...})
// pipe works, but so does injectionexecFile('ls', [dir],
(err, out) => {...})
// no pipe support, but dir can't
// break out of its own argumentIf a command genuinely requires piping, globbing, or shell redirection, execFile() can't express that directly — but that's a signal to either compose the pipeline in Node itself (spawning each stage separately and connecting streams) or, if exec() is unavoidable, ensure no part of the command string ever includes untrusted input, full stop.
spawn() is also shell-free with an argument array, similar to execFile() — the practical difference is mainly in how output is returned (streamed vs. buffered), not in the injection-safety story.