Skip to content

unsafe-child-process

Calling the child_process.exec() function, or the child_process.execFile() or child_process.spawn() functions with the {shell:true} option, execute commands in a newly spawned shell. When executed in a shell, the command can contain shell meta-characters that allow running multiple commands unexpectedly. For example, the command child_process.exec('ls;printenv') will run both ls and printenv.

It is dangerous to pass user controlled input to any exec function, but it is particularly dangerous in these three cases. If user controlled input is passed into the command string, then attackers can use this to execute malicious commands.

Examples

Insecure Example

let userInput = req.query.param1 // "; printenv"

// Example 1
child_process.exec('ls ' + userInput) // executes "ls ; printenv"

// Example 2
child_process.spawn('ls ' + userInput, {shell: true}) // executes "ls ; printenv"

// Example 3
child_process.spawn('ls', [userInput], {shell: true}) // executes "ls ; printenv"

// Example 4
child_process.execFile('ls ' + userInput, {shell: true}) // executes "ls ; printenv"

// Example 5
child_process.execFile('ls', [userInput] {shell: true}) // executes "ls ; printenv"

Secure Example

let userInput = req.query.param1 // "; printenv"

// Example 1 - Still dangerous, but less bad
child_process.spawn('ls ' + userInput) // throws an error

// Example 1.5 - Why it's still dangerous
let userInput = req.query.param1 // "../../../../etc/passwd"
child_process.spawn('cat mydir/' + userInput) // no metacharacters, so this executes "cat mydir/../../../../etc/passwd

// Example 2 - Still dangerous, but less bad
child_process.execFile('ls ' + userInput) // throws an error

// Example 3 - Best Practice
safeExec(untrustedUserInput) {
    let userDefinedIndex = parseInt(untrustedUserInput)
    let allowedCommandOptions = [
        ['.'],
        ['-la'],
        ['someSubdirectory'],
        ['-la', 'someSubdirectory]
    ]

    child_process.spawn('ls', allowedCommandOptions[userDefinedIndex])
}