Skip to content

injection fix using shell=false and directly passing args#45690

Open
ayushhgarg-work wants to merge 3 commits intoAzure:mainfrom
ayushhgarg-work:ayushhgarg/macosCommandInjection
Open

injection fix using shell=false and directly passing args#45690
ayushhgarg-work wants to merge 3 commits intoAzure:mainfrom
ayushhgarg-work:ayushhgarg/macosCommandInjection

Conversation

@ayushhgarg-work
Copy link
Member

@ayushhgarg-work ayushhgarg-work commented Mar 13, 2026

Description

Fix Applied: Changed shell=True to shell=False in commandline_utility.py and removed the " ".join(cmd_arguments) pattern. Command arguments are now passed as a list directly to subprocess.check_output, preventing shell metacharacter interpretation.

Verification: Confirmed on Windows that a malicious app_path containing shell metacharacters (&, ;) is treated as literal text and does not result in command injection. The marker file creation test passed — no arbitrary code was executed.

macOS note: No macOS machine was needed for verification. shell=False with list arguments is the standard cross-platform pattern per Python documentation and works identically on Windows, Linux, and macOS

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the local endpoints CLI helper to mitigate command-injection risk by avoiding shell=True and executing subprocesses via an argv list.

Changes:

  • Switch run_cli_command from shell=True + joined string commands to shell=False + argv list execution.
  • Update CLI command logging to print a joined representation of argv instead of the prior command_to_execute string.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 46 to +58
subprocess_args = {
"shell": True,
"shell": False,
"stderr": subprocess.STDOUT,
"env": custom_environment,
}

if not stderr_to_stdout:
subprocess_args = {"shell": True, "env": custom_environment}
subprocess_args = {"shell": False, "env": custom_environment}

if sys.version_info[0] != 2:
subprocess_args["timeout"] = timeout

output = subprocess.check_output(command_to_execute, **subprocess_args).decode(encoding="UTF-8")
output = subprocess.check_output(cmd_arguments, **subprocess_args).decode(encoding="UTF-8")
Comment on lines 30 to 33
# We do this join to construct a command because "shell=True" flag, used below, doesn't work with the vector
# argv form on a mac OS.
command_to_execute = " ".join(cmd_arguments)
# command_to_execute = " ".join(cmd_arguments)

Comment on lines 52 to +58
if not stderr_to_stdout:
subprocess_args = {"shell": True, "env": custom_environment}
subprocess_args = {"shell": False, "env": custom_environment}

if sys.version_info[0] != 2:
subprocess_args["timeout"] = timeout

output = subprocess.check_output(command_to_execute, **subprocess_args).decode(encoding="UTF-8")
output = subprocess.check_output(cmd_arguments, **subprocess_args).decode(encoding="UTF-8")
Comment on lines 34 to +35
if not do_not_print: # Avoid printing the az login service principal password, for example
print("Preparing to run CLI command: \n{}\n".format(command_to_execute))
print("Preparing to run CLI command: \n{}\n".format(" ".join(cmd_arguments)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants