Skip to content

Conversation

@rix0rrr
Copy link
Contributor

@rix0rrr rix0rrr commented Jan 21, 2026

When executing CDK apps, users specify the { "app" } command as:

  • a string (heavily advertised); or
  • a string[] (not really advertised but historically possible through specific code paths).

Traditionally we would collapse both forms to a single string, by joining the array with spaces, and then shell executing them.

Security people don't like shell execution very much, because there are chances the command gets injected by special characters and redirected to do something else. Developers don't shell shell execution very much because they have to pay attention to quoting of paths with spaces in them.

If we have a string[] already, we shouldn't need to run a command through the shell anymore, but we do. This PR changes the behavior as follows:

  • We retain the form of command line that the user gave us (string or argv array)
  • When we ultimately run the command, if the user gave us a string we'll run it through the shell but if they gave us an argv array we'll execute it directly.

This protects users against quoting issues and shell injections.

A potential breaking change of this PR could be that if people used to put shell strings in arrays, knowing full well they would execute through the shell regardless, that won't do what they expect anymore. Examples of cursedness that would fail if we merge this:

{ 
  // > used to be interpreted by the shell, now it will be treated as an argument to command.js
  "app": ["command.js", ">", "output.txt"],
}

{ 
  // Users needed to put additional quotes inside the quoted array because we would just string-join everything
  // Now the additional quotes are unnecessary
  "app": ["\"/path with spaces/command.js\"", "arg1"],
}

The risk profile of this "fix/feat" depends on how many instances of the above there are. Chances are good there will be 0 or negligibly many.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

When executing CDK apps, users specify the command as a string. The only
feasible interpretation of that is by executing the command line through
a shell, either `bash` or `cmd.exe`.

We are using shell execution on purpose:

- It's used for tests
- It's necessary on Windows to properly execute `.bat` and `.cmd` files
- Since we have historically offered it you can bet dollars to doughnuts
  that customers have built workflows depending on that.

This is all a preface to explain why we don't have an `argv` array.
Automated code scanning tools will probably complain, but we can't
change any of this. And since the source of the string and the machine
it's executing on are part of the same security domain (it's all "the
customer": the customer writes the command string, then executes it on
their own machine), that is fine.

However, historically we did do trivial parsing and preprocessing of
that `string` in order to help the user achieve success. Specifically:
if the string pointed to a `.js` file we would run that `.js` file
through a Node interpreter, even if:

- The file was not marked as executable on POSIX; or
- There was no shell association set up for `.js` files on Windows.

That light parsing used to fail in the following cases:

- If the pointed-to file had spaces in its path.
- If Node was installed in a location that had spaces in its path.

In this PR we document the choice of command line string a bit better,
and handle the cases where the file or interpreter paths can have spaces
in them.

We still don't do fully generic command line parsing, because it's
extremely complex on Windows and we can probably not do it correctly;
we're just concerned with quoting the target and interpreter.

Closes #636
@rix0rrr rix0rrr changed the base branch from main to huijbers/spaces-in-command January 21, 2026 13:48
@rix0rrr rix0rrr marked this pull request as draft January 21, 2026 13:50
auto-merge was automatically disabled January 21, 2026 13:50

Pull request was converted to draft

@rix0rrr rix0rrr changed the title feat: bypass shell execution if app is a string array feat: bypass shell if app is given as a string array Jan 21, 2026
Base automatically changed from huijbers/spaces-in-command to main January 21, 2026 14:31
@rix0rrr rix0rrr marked this pull request as ready for review January 22, 2026 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aws-cdk: cdk synth/deploy command fails with "C:\Program" is not recognized as an internal or external command

1 participant