## Summary The `docker.system_packages` field in `bentofile.yaml` accepts arbitrary strings that are interpolated directly into Dockerfile `RUN` commands without sanitization. Since `system_packages` is semantically a list of OS package names (data), users do not expect values to be interpreted as shell commands. A malicious `bentofile.yaml` achieves arbitrary command execution during `bentoml containerize` / `docker build`. ## Affected Component - `src/_bentoml_sdk/images.py:85-89` — `.format(packages=" ".join(packages))` into shell command - `src/bentoml/_internal/container/frontend/dockerfile/templates/base_debian.j2:13` — `{{ __options__system_packages | join(' ') }}` - `src/bentoml/_internal/bento/build_config.py:174` — No validation on `system_packages` - All distro install commands in `src/bentoml/_internal/container/frontend/dockerfile/__init__.py` ## Affected Versions All versions supporting `docker.system_packages` in `bentofile.yaml`, confirmed on 1.4.36. ## Steps to Reproduce 1. Create a project directory with: **service.py:** ```python import bentoml @bentoml.service class MyService: @bentoml.api def predict(self) -> str: return "hello" ``` **bentofile.yaml:** ```yaml service: "service:MyService" docker: system_packages: - "curl && id > /tmp/bentoml-pwned #" ``` 2. Run: ```bash bentoml build ``` 3. Examine the generated Dockerfile at `~/bentoml/bentos/my_service/<tag>/env/docker/Dockerfile`. Line 41 will contain: ```dockerfile RUN apt-get install -q -y -o Dpkg::Options::=--force-confdef curl && id > /tmp/bentoml-pwned # ``` 4. Running `bentoml containerize my_service:<tag>` will execute `id > /tmp/bentoml-pwned` as root during the Docker build. ## Root Cause The `system_packages` field values are treated as package names (data) by the user but are string-formatted directly into shell commands in the Dockerfile: ```python # images.py:85-89 self.commands.append( CONTAINER_METADATA[self.distro]["install_command"].format( packages=" ".join(packages) # No escaping ) ) ``` Where `install_command` is `"apt-get install -q -y -o Dpkg::Options::=--force-confdef {packages}"`. A `bash_quote` filter (wrapping `shlex.quote`) exists in the codebase and is registered in both Jinja2 environments, but it is only applied to environment variable values, never to `system_packages`. ## Impact 1. **Malicious repositories**: An attacker publishes an ML project with a crafted `bentofile.yaml`. Anyone who clones and builds it gets arbitrary code execution during `docker build`. 2. **CI/CD compromise**: Automated pipelines running `bentoml containerize` on PRs that modify `bentofile.yaml` are vulnerable. 3. **BentoCloud**: If BentoCloud builds images from user-supplied `bentofile.yaml`, this could achieve RCE on cloud infrastructure. 4. **Supply chain**: Shared bentos or model repos in the BentoML ecosystem can contain malicious configs. ## Suggested Fix ### Option 1: Input validation (recommended) Add a regex validator to `system_packages` in `build_config.py`: ```python import re VALID_PACKAGE_NAME = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9.+\-_:]*$') def _validate_system_packages(instance, attribute, value): if value is None: return for pkg in value: if not VALID_PACKAGE_NAME.match(pkg): raise BentoMLException( f"Invalid system package name: {pkg!r}. " "Package names may only contain alphanumeric characters, " "dots, plus signs, hyphens, underscores, and colons." ) system_packages: t.Optional[t.List[str]] = attr.field( default=None, validator=_validate_system_packages ) ``` ### Option 2: Output escaping Apply `shlex.quote()` to each package name before interpolation in `images.py:system_packages()` and apply the `bash_quote` Jinja2 filter in `base_debian.j2`.
## Summary The `docker.system_packages` field in `bentofile.yaml` accepts arbitrary strings that are interpolated directly into Dockerfile `RUN` commands without sanitization. Since `system_packages` is semantically a list of OS package names (data), users do not expect values to be interpreted as shell commands. A malicious `bentofile.yaml` achieves arbitrary command execution during `bentoml containerize` / `docker build`. ## Affected Component - `src/_bentoml_sdk/images.py:85-89` — `.format(packages=" ".join(packages))` into shell command - `src/bentoml/_internal/container/frontend/dockerfile/templates/base_debian.j2:13` — `{{ __options__system_packages | join(' ') }}` - `src/bentoml/_internal/bento/build_config.py:174` — No validation on `system_packages` - All distro install commands in `src/bentoml/_internal/container/frontend/dockerfile/__init__.py` ## Affected Versions All versions supporting `docker.system_packages` in `bentofile.yaml`, confirmed on 1.4.36. ## Steps to Reproduce 1. Create a project directory with: **service.py:** ```python import bentoml @bentoml.service class MyService: @bentoml.api def predict(self) -> str: return "hello" ``` **bentofile.yaml:** ```yaml service: "service:MyService" docker: system_packages: - "curl && id > /tmp/bentoml-pwned #" ``` 2. Run: ```bash bentoml build ``` 3. Examine the generated Dockerfile at `~/bentoml/bentos/my_service/<tag>/env/docker/Dockerfile`. Line 41 will contain: ```dockerfile RUN apt-get install -q -y -o Dpkg::Options::=--force-confdef curl && id > /tmp/bentoml-pwned # ``` 4. Running `bentoml containerize my_service:<tag>` will execute `id > /tmp/bentoml-pwned` as root during the Docker build. ## Root Cause The `system_packages` field values are treated as package names (data) by the user but are string-formatted directly into shell commands in the Dockerfile: ```python # images.py:85-89 self.commands.append( CONTAINER_METADATA[self.distro]["install_command"].format( packages=" ".join(packages) # No escaping ) ) ``` Where `install_command` is `"apt-get install -q -y -o Dpkg::Options::=--force-confdef {packages}"`. A `bash_quote` filter (wrapping `shlex.quote`) exists in the codebase and is registered in both Jinja2 environments, but it is only applied to environment variable values, never to `system_packages`. ## Impact 1. **Malicious repositories**: An attacker publishes an ML project with a crafted `bentofile.yaml`. Anyone who clones and builds it gets arbitrary code execution during `docker build`. 2. **CI/CD compromise**: Automated pipelines running `bentoml containerize` on PRs that modify `bentofile.yaml` are vulnerable. 3. **BentoCloud**: If BentoCloud builds images from user-supplied `bentofile.yaml`, this could achieve RCE on cloud infrastructure. 4. **Supply chain**: Shared bentos or model repos in the BentoML ecosystem can contain malicious configs. ## Suggested Fix ### Option 1: Input validation (recommended) Add a regex validator to `system_packages` in `build_config.py`: ```python import re VALID_PACKAGE_NAME = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9.+\-_:]*$') def _validate_system_packages(instance, attribute, value): if value is None: return for pkg in value: if not VALID_PACKAGE_NAME.match(pkg): raise BentoMLException( f"Invalid system package name: {pkg!r}. " "Package names may only contain alphanumeric characters, " "dots, plus signs, hyphens, underscores, and colons." ) system_packages: t.Optional[t.List[str]] = attr.field( default=None, validator=_validate_system_packages ) ``` ### Option 2: Output escaping Apply `shlex.quote()` to each package name before interpolation in `images.py:system_packages()` and apply the `bash_quote` Jinja2 filter in `base_debian.j2`.
Update bentoml to 1.4.37 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scanBentoML has Dockerfile Command Injection via system_packages in bentofile.yaml affects bentoml (pip). Severity is high. ## Summary The `docker.system_packages` field in `bentofile.yaml` accepts arbitrary strings that are interpolated directly into Dockerfile `RUN` commands without sanitization. Since `system_packages` is semantically a list of OS package names (data), users do not expect values to be interpreted as shell commands. A malicious `bentofile.yaml` achieves arbitrary command execution during `bentoml containerize` / `docker build`. ## Affected Component - `src/_bentoml_sdk/images.py:85-89` — `.format(packages=" ".join(packages))` into shell command - `src/bentoml/_internal/container/frontend/dockerfile/templates/base_debian.j2:13` — `{{ __options__system_packages | join(' ') }}` - `src/bentoml/_internal/bento/build_config.py:174` — No validation on `system_packages` - All distro install commands in `src/bentoml/_internal/container/frontend/dockerfile/__init__.py` ## Affected Versions All versions supporting `docker.system_packages` in `bentofile.yaml`, confirmed on 1.4.36. ## Steps to Reproduce 1. Create a project directory with: **service.py:** ```python import bentoml @bentoml.service class MyService: @bentoml.api def predict(self) -> str: return "hello" ``` **bentofile.yaml:** ```yaml service: "service:MyService" docker: system_packages: - "curl && id > /tmp/bentoml-pwned #" ``` 2. Run: ```bash bentoml build ``` 3. Examine the generated Dockerfile at `~/bentoml/bentos/my_service/<tag>/env/docker/Dockerfile`. Line 41 will contain: ```dockerfile RUN apt-get install -q -y -o Dpkg::Options::=--force-confdef curl && id > /tmp/bentoml-pwned # ``` 4. Running `bentoml containerize my_service:<tag>` will execute `id > /tmp/bentoml-pwned` as root during the Docker build. ## Root Cause The `system_packages` field values are treated as package names (data) by the user but are string-formatted directly into shell commands in the Dockerfile: ```python # images.py:85-89 self.commands.append( CONTAINER_METADATA[self.distro]["install_command"].format( packages=" ".join(packages) # No escaping ) ) ``` Where `install_command` is `"apt-get install -q -y -o Dpkg::Options::=--force-confdef {packages}"`. A `bash_quote` filter (wrapping `shlex.quote`) exists in the codebase and is registered in both Jinja2 environments, but it is only applied to environment variable values, never to `system_packages`. ## Impact 1. **Malicious repositories**: An attacker publishes an ML project with a crafted `bentofile.yaml`. Anyone who clones and builds it gets arbitrary code execution during `docker build`. 2. **CI/CD compromise**: Automated pipelines running `bentoml containerize` on PRs that modify `bentofile.yaml` are vulnerable. 3. **BentoCloud**: If BentoCloud builds images from user-supplied `bentofile.yaml`, this could achieve RCE on cloud infrastructure. 4. **Supply chain**: Shared bentos or model repos in the BentoML ecosystem can contain malicious configs. ## Suggested Fix ### Option 1: Input validation (recommended) Add a regex validator to `system_packages` in `build_config.py`: ```python import re VALID_PACKAGE_NAME = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9.+\-_:]*$') def _validate_system_packages(instance, attribute, value): if value is None: return for pkg in value: if not VALID_PACKAGE_NAME.match(pkg): raise BentoMLException( f"Invalid system package name: {pkg!r}. " "Package names may only contain alphanumeric characters, " "dots, plus signs, hyphens, underscores, and colons." ) system_packages: t.Optional[t.List[str]] = attr.field( default=None, validator=_validate_system_packages ) ``` ### Option 2: Output escaping Apply `shlex.quote()` to each package name before interpolation in `images.py:system_packages()` and apply the `bash_quote` Jinja2 filter in `base_debian.j2`.
AI coding agents often install or upgrade packages automatically in pip. A high vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| bentomlpip | <=1.4.36 | 1.4.37 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL GuardUpdate bentoml to 1.4.37 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scanBentoML has Dockerfile Command Injection via system_packages in bentofile.yaml affects bentoml (pip). Severity is high. ## Summary The `docker.system_packages` field in `bentofile.yaml` accepts arbitrary strings that are interpolated directly into Dockerfile `RUN` commands without sanitization. Since `system_packages` is semantically a list of OS package names (data), users do not expect values to be interpreted as shell commands. A malicious `bentofile.yaml` achieves arbitrary command execution during `bentoml containerize` / `docker build`. ## Affected Component - `src/_bentoml_sdk/images.py:85-89` — `.format(packages=" ".join(packages))` into shell command - `src/bentoml/_internal/container/frontend/dockerfile/templates/base_debian.j2:13` — `{{ __options__system_packages | join(' ') }}` - `src/bentoml/_internal/bento/build_config.py:174` — No validation on `system_packages` - All distro install commands in `src/bentoml/_internal/container/frontend/dockerfile/__init__.py` ## Affected Versions All versions supporting `docker.system_packages` in `bentofile.yaml`, confirmed on 1.4.36. ## Steps to Reproduce 1. Create a project directory with: **service.py:** ```python import bentoml @bentoml.service class MyService: @bentoml.api def predict(self) -> str: return "hello" ``` **bentofile.yaml:** ```yaml service: "service:MyService" docker: system_packages: - "curl && id > /tmp/bentoml-pwned #" ``` 2. Run: ```bash bentoml build ``` 3. Examine the generated Dockerfile at `~/bentoml/bentos/my_service/<tag>/env/docker/Dockerfile`. Line 41 will contain: ```dockerfile RUN apt-get install -q -y -o Dpkg::Options::=--force-confdef curl && id > /tmp/bentoml-pwned # ``` 4. Running `bentoml containerize my_service:<tag>` will execute `id > /tmp/bentoml-pwned` as root during the Docker build. ## Root Cause The `system_packages` field values are treated as package names (data) by the user but are string-formatted directly into shell commands in the Dockerfile: ```python # images.py:85-89 self.commands.append( CONTAINER_METADATA[self.distro]["install_command"].format( packages=" ".join(packages) # No escaping ) ) ``` Where `install_command` is `"apt-get install -q -y -o Dpkg::Options::=--force-confdef {packages}"`. A `bash_quote` filter (wrapping `shlex.quote`) exists in the codebase and is registered in both Jinja2 environments, but it is only applied to environment variable values, never to `system_packages`. ## Impact 1. **Malicious repositories**: An attacker publishes an ML project with a crafted `bentofile.yaml`. Anyone who clones and builds it gets arbitrary code execution during `docker build`. 2. **CI/CD compromise**: Automated pipelines running `bentoml containerize` on PRs that modify `bentofile.yaml` are vulnerable. 3. **BentoCloud**: If BentoCloud builds images from user-supplied `bentofile.yaml`, this could achieve RCE on cloud infrastructure. 4. **Supply chain**: Shared bentos or model repos in the BentoML ecosystem can contain malicious configs. ## Suggested Fix ### Option 1: Input validation (recommended) Add a regex validator to `system_packages` in `build_config.py`: ```python import re VALID_PACKAGE_NAME = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9.+\-_:]*$') def _validate_system_packages(instance, attribute, value): if value is None: return for pkg in value: if not VALID_PACKAGE_NAME.match(pkg): raise BentoMLException( f"Invalid system package name: {pkg!r}. " "Package names may only contain alphanumeric characters, " "dots, plus signs, hyphens, underscores, and colons." ) system_packages: t.Optional[t.List[str]] = attr.field( default=None, validator=_validate_system_packages ) ``` ### Option 2: Output escaping Apply `shlex.quote()` to each package name before interpolation in `images.py:system_packages()` and apply the `bash_quote` Jinja2 filter in `base_debian.j2`.
AI coding agents often install or upgrade packages automatically in pip. A high vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| bentomlpip | <=1.4.36 | 1.4.37 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL Guard