Skip to content

Windows cmd.exe Command Injection via Newline Characters #179

@dfzysmy2tf-create

Description

@dfzysmy2tf-create

File: node_modules/cross-spawn/lib/util/escape.js

Vulnerability Description

The escapeArgument() function of cross-spawn escapes shell metacharacters (e.g., !%^&()<>|") for Windows cmd.exe by prefixing them with ^, but fails to handle \r (carriage return) and \n (newline) characters. In Windows cmd.exe, \r\n is interpreted as a command separator (equivalent to pressing Enter to execute a new command).
Vulnerable Code

// cross-spawn/lib/util/escape.js
const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;  // ❌ Does not include \r\n

function escapeArgument(arg, doubleEscapeMetaChars) {
    arg = `${arg}`;
    // ... Handles backslashes and double quotes ...
    arg = `"${arg}"`;
    arg = arg.replace(metaCharsRegExp, '^$&');  // ❌ \r\n not in escape scope
    return arg;
}

Exploitation Conditions

Attacker controls parameters passed to cross-spawn
Target system is Windows
Command is executed via cmd.exe (i.e., shell: true or non-.exe paths in cross-spawn)

PoC Attack Example

const spawn = require('cross-spawn');

// Malicious argument containing newline characters
const maliciousArg = 'innocent\r\necho PWNED';

// On Windows, this executes two commands
spawn('echo', [maliciousArg], { shell: true });
// Actual execution:
// cmd.exe /d /s /c "echo "innocent
// echo PWNED""

Actual Impact

In the npm context, if fields in package.json (e.g., bin paths, scripts parameters) contain newline characters, command injection may be triggered on Windows.

Remediation Suggestions

// Add newline character handling to escape function
function escapeArgument(arg) {
    arg = `${arg}`;
    // Remove or escape newline characters
    arg = arg.replace(/[\r\n]/g, '');  // ✅ Removes newline characters
    // ... Remaining escape logic ...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions