PoC β OS command injection in BentoML Dockerfile generation via docker.env (dict form, v1 template)
Security proof-of-concept for an OS command injection (CWE-78) in bentoml/BentoML @ v1.4.39 (latest release). Reported via huntr.
An untrusted bentofile.yaml sets docker.env in dict form, whose keys/values are not validated
(unlike the list form) and are interpolated raw into ARG/ENV directives of the generated v1
Dockerfile. A newline injects an attacker-controlled RUN directive, executed on the victim host at
bentoml containerize / docker build. Inert trigger artifact; benign marker only.
Root cause β different engine than CVE-2026-44346
- Source (unvalidated):
_convert_env(build_config.py:138-140) β the list form is regex-validated (^(\w+)=([\.\w\-,\/]+)$, rejects\n); the dict form returns{str(k): str(v)}with no validation. - Sink (raw):
base.j2:47-48βARG {{ key }}={{ value }}/ENV {{ key }}=${{ key }}, nonormalize_line/bash_quote(contrastbase.j2:21base_imagewhich is filtered).
The fix for CVE-2026-44346 only patched the v2 engine (base_v2.j2:70/72, envs[*].name) β it never
iterates docker.env and never touches the v1 base.j2 engine. So docker.env (dict) remains raw at
v1.4.39 and on main. The v1 template is selected whenever the bento uses docker.cuda_version (GPU),
conda, docker.dockerfile_template, or python.wheels β mainstream ML configs.
Same threat model as the four rewarded BentoML Dockerfile-injection CVEs (-33744, -35043, -44345, -44346): untrusted bento β injected Dockerfile directive β command execution at build.
Files
| file | role |
|---|---|
poc.py |
drives BentoML Dockerfile generation with a malicious docker.env dict β poisoned Dockerfile |
malicious_bentofile.yaml |
illustration of the injected docker.env + a v1-trigger (cuda_version) |
fire.log |
rendered Dockerfile excerpt showing the injected RUN directive |
Reproduce
pip install bentoml==1.4.39
python poc.py # -> generated Dockerfile contains a standalone `RUN touch /tmp/huntr_bentoml_003`
Fix
Validate the dict form of docker.env like the list form (reject newlines / shell metacharacters in keys
and values), and/or apply |normalize_line to base.j2:47-48.