镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Disallow args in child_process execFile/spawn when the shell option is true #57143

Description

@mohd-akram

The execFile and spawn functions allow passing the shell option to run a command using a shell. Despite the fact that setting this option to true means that arguments are no longer properly preserved, these functions continue to accept an array of arguments, giving the false impression that there is some isolation/escaping when behind the scenes the arguments are just concatenated. This can make it trivial to introduce bugs and security issues, and the behavior is also not aligned with exec which only accepts a single command string that is passed to the shell. To make this point clearer, invocations like this are currently accepted, which shouldn't be the case:

execFileSync('echo "hello', ['world"'], { shell: true }).toString()

Activity

  1. DanielVenable commented on Feb 20, 2025

    @DanielVenable
    Contributor

    What behavior do you think it should have? Should it throw an error when the second argument isn't empty?

  2. mohd-akram commented on Feb 21, 2025

    @mohd-akram
    ContributorAuthor

    Since spawn/execFile already allow omitting args, they should throw if it is provided.

  3. DanielVenable commented on Feb 22, 2025

    @DanielVenable
    Contributor

    What kind of error should it throw?

  4. added
    child_processIssues and PRs related to the child_process subsystem.
    on Feb 25, 2025
  5. added a commit that references this issue on May 7, 2025
  6. mojavelinux commented on May 7, 2025

    @mojavelinux

    This is an outrageous change. There are applications that rely on being able to pass arguments to commands with the shell option is true. In fact, it's the only way to invoke npm on Windows in recent versions of Node.js. Yes, it does require extra care to escape arguments properly, but that is the responsibility of the developer using the API. Forbidding this cripples the whole functionality of the execFile and spawn.

  7. mohd-akram commented on May 7, 2025

    @mohd-akram
    ContributorAuthor

    It's not forbidden. Instead of:

    execFileSync('npm', ['install'], { shell: true })

    do:

    execFileSync('npm install', { shell: true })

    In fact, it's the only way to invoke npm on Windows in recent versions of Node.js.

    I created batspawn for this purpose to safely run commands on Windows without requiring setting shell: true.

  8. mojavelinux commented on May 7, 2025

    @mojavelinux

    The API has clearly stated up to this point that that arguments are not further escaped when shell is true. There's no justification for taking this feature away and forcing the use of a command string that embeds the arguments. That's just petty and it breaks code unnecessarily.

    I, too, developed a library that safely runs commands on Windows, and now that library and everything that depends on it is now broken.

  9. prabhu commented on May 29, 2025

    @prabhu

    This change is going to require a significant rewrite to one of my projects. While exec doesn't accept args, spawn does so asking the users to carefully perform string concatenation rather than doing it automatically behind the scenes doesn't really improve security.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    child_processIssues and PRs related to the child_process subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions