Skip to content

Commit 9684e28

Browse files
committed
double quote eval to protect from quotes escape
Signed-off-by: Aleksei Stepanov <penguinolog@gmail.com>
1 parent c7e144d commit 9684e28

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

exec_helpers/_ssh_client_base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ def _prepare_command(self, cmd: str, chroot_path: typing.Optional[str] = None) -
410410
return super()._prepare_command(cmd=cmd, chroot_path=chroot_path)
411411
if any((chroot_path, self._chroot_path)):
412412
target_path: str = shlex.quote(chroot_path if chroot_path else self._chroot_path) # type: ignore
413-
return f'chroot {target_path} sudo sh -c "eval {shlex.quote(cmd)}"'
413+
quoted_command: str = shlex.quote(cmd)
414+
return f'chroot {target_path} sudo sh -c {shlex.quote(f"eval {quoted_command}")}'
414415
return f'sudo -S sh -c "eval {shlex.quote(cmd)}"'
415416

416417
# noinspection PyMethodOverriding

exec_helpers/api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ def _prepare_command(self, cmd: str, chroot_path: typing.Optional[str] = None) -
229229
"""
230230
if any((chroot_path, self._chroot_path)):
231231
target_path: str = shlex.quote(chroot_path if chroot_path else self._chroot_path) # type: ignore
232-
return f'chroot {target_path} sh -c "eval {shlex.quote(cmd)}"'
232+
quoted_command = shlex.quote(cmd)
233+
return f'chroot {target_path} sh -c {shlex.quote(f"eval {quoted_command}")}'
233234
return cmd
234235

235236
def execute_async( # pylint: disable=missing-param-doc,differing-param-doc,differing-type-doc

test/test_ssh_client_execute_async_special.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def read_stream(stream: FakeFileStream) -> typing.Tuple[bytes, ...]:
5656

5757
command = "ls ~\nline 2\nline 3\nline с кирилицей"
5858
cmd_execute = f"{command}\n"
59+
quoted_command = shlex.quote(command)
5960
command_log = f"Executing command:\n{command.rstrip()!r}\n"
6061
stdout_src = (b" \n", b"2\n", b"3\n", b" \n")
6162
stderr_src = (b" \n", b"0\n", b"1\n", b" \n")
@@ -233,7 +234,7 @@ def test_011_execute_async_chroot_cmd(ssh, ssh_transport_channel):
233234
ssh_transport_channel.assert_has_calls(
234235
(
235236
mock.call.makefile_stderr("rb"),
236-
mock.call.exec_command(f'chroot / sh -c "eval {shlex.quote(command)}"\n'),
237+
mock.call.exec_command(f'chroot / sh -c {shlex.quote(f"eval {quoted_command}")}\n'),
237238
)
238239
)
239240

@@ -245,7 +246,7 @@ def test_012_execute_async_chroot_context(ssh, ssh_transport_channel):
245246
ssh_transport_channel.assert_has_calls(
246247
(
247248
mock.call.makefile_stderr("rb"),
248-
mock.call.exec_command(f'chroot / sh -c "eval {shlex.quote(command)}"\n'),
249+
mock.call.exec_command(f'chroot / sh -c {shlex.quote(f"eval {quoted_command}")}\n'),
249250
)
250251
)
251252

0 commit comments

Comments
 (0)