Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@xsmile
Copy link
Contributor

@xsmile xsmile commented Jul 7, 2025

What does this PR do?

Change the behavior of the cmdmod execution module.

shell / python_shell

Respect user input for the shell parameter. Same as python_shell, it is disabled by default for all functions except cmd.shell. This prevents unnecessary calls to the shell and possibly unsafe command executions. cmd.run and other similar functions now require shell to be specified explicitly if shell functionality is required.

cmd._run

  • the command list / string is kept as is without altering the command behaviour. Special characters and whitespaces are handled by subprocess.list2cmdline only if required in case the shell is cmd.exe or if impersonating another user and passing the command string to CreateProcess.
  • run PowerShell scripts via -File instead of -Command. This makes it possible to pass arguments as a list and not having to worry about escaping characters. In contrast to the previous behavior with -Command, the arguments are not evaluated as commands. When PowerShell commands are a requirement, cmd.shell or cmd.powershell should be used instead, e.g. Windows: Using inline powershell in args with cmd.script and shell: powershell #56195 .

cmd.script

  • always remove the temporary script, even if it fails to be executed
  • automatically suggest a shell when a Windows script with a known file extension is found
  • allow to pass arguments as a list

cmd.powershell

  • do not silently fail and report success when a PowerShell command fails to run

What issues does this PR fix or reference?

#56195
#68096
#68118

Merge requirements satisfied?

Commits signed with GPG?

No

@xsmile xsmile requested a review from a team as a code owner July 7, 2025 13:32
@welcome
Copy link

welcome bot commented Jul 7, 2025

Hi there! Welcome to the Salt Community! Thank you for making your first contribution. We have a lengthy process for issues and PRs. Someone from the Core Team will follow up as soon as possible. In the meantime, here’s some information that may help as you continue your Salt journey.
Please be sure to review our Code of Conduct. Also, check out some of our community resources including:

There are lots of ways to get involved in our community. Every month, there are around a dozen opportunities to meet with other contributors and the Salt Core team and collaborate in real time. The best way to keep track is by subscribing to the Salt Community Events Calendar.
If you have additional questions, email us at [email protected]. We’re glad you’ve joined our community and look forward to doing awesome things with you!

Copy link
Contributor

@twangboy twangboy left a comment

Choose a reason for hiding this comment

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

I have a few questions about some of the tests. Also, this needs a changelog. Additionally, please make these changes against the 3006.x branch as these issue also exist there.

@twangboy twangboy added the test:full Run the full test suite label Jul 7, 2025
@twangboy twangboy added this to the Sulfur v3006.14 milestone Jul 7, 2025
@twangboy twangboy added needs-changelog needs-rebase Needs to be rebased, against either the current branch or a different one labels Jul 9, 2025
@xsmile xsmile changed the base branch from 3007.x to 3006.x July 9, 2025 18:29
Copy link
Contributor

@twangboy twangboy left a comment

Choose a reason for hiding this comment

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

A few questions and changes. Thanks for adding a changelog.

@twangboy
Copy link
Contributor

twangboy commented Jul 9, 2025

Got some pre-commit failures

--- a/tests/integration/modules/test_cmdmod.py
+++ b/tests/integration/modules/test_cmdmod.py
@@ -590,9 +590,7 @@ class CMDModuleTest(ModuleCase):
         self.assertEqual(out, "")
 
         # cmd.run_stderr
-        out = self.run_function(
-            "cmd.shell", ls_command, shell=shell, hide_output=True
-        )
+        out = self.run_function("cmd.shell", ls_command, shell=shell, hide_output=True)
         self.assertEqual(out, "")

twangboy
twangboy previously approved these changes Jul 25, 2025
@xsmile
Copy link
Contributor Author

xsmile commented Jul 25, 2025

Missed that one, sorry.

@dwoz dwoz merged commit 2459d52 into saltstack:3006.x Jul 30, 2025
1321 of 1323 checks passed
new_cmd = [path, *args] if args else [path]
else:
cmd_path = _cmd_quote(path)
new_cmd = [path, str(args)] if args else [path]
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not look correct. This appears to be taking a str of potentially multiple arguments and passing it as just the first argument.

Also the docstring only states that a str is even supported and not a list/tuple

:param str args: String of command line args to pass to the script. Only
        used if no args are specified as part of the `name` argument. To pass a
string containing spaces in YAML, you will need to doubly-quote it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. This should be fixed with https://github.com/saltstack/salt/pull/68301/files#diff-700b7d75700c9eafa3ee48d01236e59f37b2ed81d998267136fbcc0224766497R3007 , althrough passing multiple arguments with a single string might be unreliable, especially on Windows.

Copy link
Contributor

@bdrx312 bdrx312 Sep 1, 2025

Choose a reason for hiding this comment

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

Nice. Thanks. I think these improvements are nice. It bothered me since starting to use salt that you could not pass lists like you could with the subprocess module to avoid escaping issues.

# from the script. Otherwise, it will always return 1 on any non-zero
# exit code failure. Issue: #60884
new_cmd.append(f'"& {cmd.strip()}; exit $LASTEXITCODE"')
new_cmd.append("-File")
Copy link
Contributor

@twangboy twangboy Sep 10, 2025

Choose a reason for hiding this comment

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

@xsmile Assume C:\temp\test.ps1 with the following content:

[CmdLetBinding()]
Param([SecureString] $SecureString)
$Credential = New-Object System.Net.NetworkCredential("DummyId", $SecureString)
$Credential.Password

As noted in the comments, using -File does not work:

PS C:\src> powershell.exe -File C:\Temp\test.ps1 -SecureString (ConvertTo-SecureString -String "I like cheese" -AsPlainText -Force) -ErrorAction Stop

You must use -Command to evaluate powershell commands in arguments to a script:

PS C:\src> powershell.exe -Command "& { C:\Temp\test.ps1 -SecureString (ConvertTo-SecureString -String 'I like cheese' -AsPlainText -Force) -ErrorAction Stop }"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@twangboy I would argue that by using -Command you are not directly executing a script but running a PowerShell command executing a script. This introduces issues like the need to carefully handle special characters, which is an impossible task since user input is not known in advance. Parameters can be evaluated as code, allowing for code injection without the need to know the script content.

IMHO the proper way to handle SecureString would be to use a dedicated module that takes care of encrypting such parameters and passing them to the final script.

Running PS C:\src> powershell.exe -Command "& { C:\Temp\test.ps1 -SecureString (ConvertTo-SecureString -String 'I like cheese' -AsPlainText -Force) -ErrorAction Stop }" probably defeats the purpose of SecureString since the password will be visible in plain text on the command line and can be logged.

Copy link
Contributor

Choose a reason for hiding this comment

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

The password is just an example for evaluating powershell code as arguments. This was working before these changes. Now they aren't. If you can run it in a powershell prompt, you should be able to run it with Salt.

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

Labels

test:full Run the full test suite

Projects

None yet

4 participants