Skip to content

Commit 7a14112

Browse files
Megan Wilhites0undt3ch
authored andcommitted
1 parent 286d55e commit 7a14112

File tree

4 files changed

+416
-51
lines changed

4 files changed

+416
-51
lines changed

changelog/cve-2023-34049.security.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix CVE-2023-34049 by ensuring we do not use a predictable name for the script and correctly check returncode of scp command.
2+
This only impacts salt-ssh users using the pre-flight option.

salt/client/ssh/__init__.py

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
import logging
1212
import multiprocessing
1313
import os
14+
import pathlib
1415
import queue
1516
import re
1617
import shlex
18+
import shutil
1719
import subprocess
1820
import sys
1921
import tarfile
@@ -467,7 +469,14 @@ def key_deploy(self, host, ret):
467469
if target.get("passwd", False) or self.opts["ssh_passwd"]:
468470
self._key_deploy_run(host, target, False)
469471
return ret
470-
if ret[host].get("stderr", "").count("Permission denied"):
472+
stderr = ret[host].get("stderr", "")
473+
# -failed to upload file- is detecting scp errors
474+
# Errors to ignore when Permission denied is in the stderr. For example
475+
# scp can get a permission denied on the target host, but they where
476+
# able to accurate authenticate against the box
477+
ignore_err = ["failed to upload file"]
478+
check_err = [x for x in ignore_err if stderr.count(x)]
479+
if "Permission denied" in stderr and not check_err:
471480
target = self.targets[host]
472481
# permission denied, attempt to auto deploy ssh key
473482
print(
@@ -1007,11 +1016,32 @@ def run_ssh_pre_flight(self):
10071016
"""
10081017
Run our pre_flight script before running any ssh commands
10091018
"""
1010-
script = os.path.join(tempfile.gettempdir(), self.ssh_pre_file)
1011-
1012-
self.shell.send(self.ssh_pre_flight, script)
1019+
with tempfile.NamedTemporaryFile() as temp:
1020+
# ensure we use copyfile to not copy the file attributes
1021+
# we want to ensure we use the perms set by the secure
1022+
# NamedTemporaryFile
1023+
try:
1024+
shutil.copyfile(self.ssh_pre_flight, temp.name)
1025+
except OSError as err:
1026+
return (
1027+
"",
1028+
f"Could not copy pre flight script {self.ssh_pre_flight} to temporary path",
1029+
1,
1030+
)
1031+
target_script = f".{pathlib.Path(temp.name).name}"
1032+
log.trace(f"Copying the pre flight script {self.ssh_pre_file} to target")
1033+
stdout, stderr, retcode = self.shell.send(temp.name, target_script)
1034+
if retcode != 0:
1035+
# We could not copy the script to the target
1036+
log.error(
1037+
f"Could not copy the pre flight script {self.ssh_pre_file} to target"
1038+
)
1039+
return stdout, stderr, retcode
10131040

1014-
return self.execute_script(script, script_args=self.ssh_pre_flight_args)
1041+
log.trace(f"Executing the pre flight script {self.ssh_pre_file} on target")
1042+
return self.execute_script(
1043+
target_script, script_args=self.ssh_pre_flight_args
1044+
)
10151045

10161046
def check_thin_dir(self):
10171047
"""
@@ -1388,18 +1418,20 @@ def shim_cmd(self, cmd_str, extension="py"):
13881418
return self.shell.exec_cmd(cmd_str)
13891419

13901420
# Write the shim to a temporary file in the default temp directory
1391-
with tempfile.NamedTemporaryFile(
1392-
mode="w+b", prefix="shim_", delete=False
1393-
) as shim_tmp_file:
1421+
with tempfile.NamedTemporaryFile(mode="w+b", delete=False) as shim_tmp_file:
13941422
shim_tmp_file.write(salt.utils.stringutils.to_bytes(cmd_str))
13951423

13961424
# Copy shim to target system, under $HOME/.<randomized name>
1397-
target_shim_file = ".{}.{}".format(
1398-
binascii.hexlify(os.urandom(6)).decode("ascii"), extension
1399-
)
1425+
target_shim_file = f".{pathlib.Path(shim_tmp_file.name).name}"
1426+
14001427
if self.winrm:
14011428
target_shim_file = saltwinshell.get_target_shim_file(self, target_shim_file)
1402-
self.shell.send(shim_tmp_file.name, target_shim_file, makedirs=True)
1429+
stdout, stderr, retcode = self.shell.send(
1430+
shim_tmp_file.name, target_shim_file, makedirs=True
1431+
)
1432+
if retcode != 0:
1433+
log.error(f"Could not copy the shim script to target")
1434+
return stdout, stderr, retcode
14031435

14041436
# Remove our shim file
14051437
try:

0 commit comments

Comments
 (0)