提交 #850895: Bentoml OpenLLM 0.6.30 Command Injection信息

标题Bentoml OpenLLM 0.6.30 Command Injection
描述https://github.com/bentoml/OpenLLM OpenLLM uses `asyncio.create_subprocess_shell` to launch model servers, constructing the shell command by joining a Python list into a single string with `' '.join(...)`. Model version and name identifiers are taken directly from directory names in a cloned model repository without any sanitization. An attacker who controls a model repository can name a directory to contain shell metacharacters (for example `;`, `$()`, `` ` ``), causing arbitrary commands to execute on the victim's machine when the victim runs `openllm run` or `openllm serve` using the attacker-controlled repository. ### Details The root cause is in `src/openllm/common.py` at the `async_run_command` function (lines 425-431): ```python proc = await asyncio.create_subprocess_shell( ' '.join(map(str, cmd)), stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=cwd, env=env, ) ``` The `cmd` list is joined into a single string and handed to a shell interpreter. Any shell metacharacters present in the joined string are evaluated by the shell. The `cmd` list is built in `src/openllm/local.py` at `_get_serve_cmd` (lines 31-44): ```python def _get_serve_cmd(bento, port=3000, cli_args=None): cmd = ['bentoml', 'serve', bento.bentoml_tag] if port != 3000: cmd += ['--port', str(port)] if cli_args: for arg in cli_args: cmd += ['--arg', arg] return cmd, EnvVars(...) ``` `bento.bentoml_tag` is defined in `src/openllm/common.py` (line 179): ```python @property def bentoml_tag(self) -> str: return f'{self.path.parent.name}:{self.path.name}' ``` `self.path` is a `pathlib.Path` pointing to the directory of the model version inside the cloned repository. `self.path.parent.name` is the model name directory and `self.path.name` is the version directory. Neither is sanitized or quoted before being inserted into the list that is subsequently joined for the shell. The contrast with safe usage is visible in the same function: the `shlex.quote` call at line 405 is used only for cosmetic display output, not for the actual subprocess invocation: ```python output(f'$ export {k}={shlex.quote(v)}', style='orange') # display only -- not the real command ``` The synchronous `run_command` function (also in common.py) uses `subprocess.run(cmd, ...)` with a list (no shell=True), so it is not vulnerable. Only `async_run_command`, called exclusively from the `openllm run` path, is affected.
来源⚠️ https://github.com/bentoml/OpenLLM/issues/1229
用户
 geochen (UID 78995)
提交2026-06-07 10時18分 (1 月前)
管理2026-07-08 09時41分 (1 month later)
状态已接受
VulDB条目376786 [bentoml OpenLLM 0.6.30 Model Repository Directory Name src/openllm/common.py async_run_command cmd 权限提升]
积分20

Want to know what is going to be exploited?

We predict KEV entries!