From 8ed74a33a9686b39c3f3a05be323dc17cf3b2e9e Mon Sep 17 00:00:00 2001 From: NguyenCong2k <123174148+NguyenCong2k@users.noreply.github.com> Date: Mon, 11 May 2026 10:26:08 +0700 Subject: [PATCH 1/2] Avoid shell in async command runner --- src/openllm/common.py | 7 ++++--- tests/test_common.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/test_common.py diff --git a/src/openllm/common.py b/src/openllm/common.py index c3646ba69..ba82846db 100644 --- a/src/openllm/common.py +++ b/src/openllm/common.py @@ -422,8 +422,8 @@ async def async_run_command( proc = None try: - proc = await asyncio.create_subprocess_shell( - ' '.join(map(str, cmd)), + proc = await asyncio.create_subprocess_exec( + *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=cwd, @@ -435,7 +435,8 @@ async def async_run_command( raise typer.Exit(1) finally: if proc: - proc.send_signal(signal.SIGINT) + if proc.returncode is None: + proc.send_signal(signal.SIGINT) await proc.wait() diff --git a/tests/test_common.py b/tests/test_common.py new file mode 100644 index 000000000..a9388523e --- /dev/null +++ b/tests/test_common.py @@ -0,0 +1,23 @@ +import asyncio +import os + +from openllm.common import async_run_command + + +def test_async_run_command_does_not_invoke_shell(tmp_path): + marker = tmp_path / 'shell_injection_marker.txt' + if os.name == 'nt': + separator = '&' + payload = ['cmd', '/c', f'echo PWNED>{marker}'] + else: + separator = ';' + payload = ['sh', '-c', f'echo PWNED > {marker}'] + + async def run() -> None: + cmd = ['python', '-c', 'pass', separator, *payload] + async with async_run_command(cmd, cwd=str(tmp_path), silent=True) as proc: + await proc.wait() + + asyncio.run(run()) + + assert not marker.exists() From 4eb4f4e3af53770ace8c3375e080447d637c83c0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 03:29:05 +0000 Subject: [PATCH 2/2] ci: auto fixes from pre-commit.ci For more information, see https://pre-commit.ci --- src/openllm/common.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/openllm/common.py b/src/openllm/common.py index ba82846db..f17103f6b 100644 --- a/src/openllm/common.py +++ b/src/openllm/common.py @@ -423,11 +423,7 @@ async def async_run_command( proc = None try: proc = await asyncio.create_subprocess_exec( - *cmd, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, - cwd=cwd, - env=env, + *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=cwd, env=env ) yield proc except subprocess.CalledProcessError: