VAITP Dataset

← Back to the dataset

CVE-2026-40610

BentoML follows symlinks during build, leaking host files into the Bento.

  • CVSS 5.5
  • CWE-59
  • Information Leakage
  • Local

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. In versions 1.4.38 and prior, the 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. An attacker can exfiltrate local files from the build host into the Bento artifact, exposing secrets such as cloud credentials, SSH keys, API tokens, environment files, or other sensitive local configurations. Because Bento artifacts are commonly exported, uploaded, stored, or containerized after build, the leaked file contents can spread beyond the original build machine. This issue has been fixed in version 1.4.39.

CVSS base score
5.5
Published
2026-05-22
OWASP
A01 Broken Access Control
Orthogonal defect classification
Build/Package/Merge
Code defect classification
Missing Check
Category
Information Leakage
Subcategory
Path Traversal
Accessibility scope
Local
Impact
Information Disclosure
Affected component
BentoML
Fixed by upgrading
Yes

Solution

Upgrade BentoML to version 1.4.39 or later.

Vulnerable code sample

import os
import shutil

# This function simulates the vulnerable file packaging workflow in BentoML
# versions 1.4.38 and prior. It represents a part of the 'bentoml build'
# command.
def vulnerable_build_process(build_context_dir, output_dir):
    """
    Copies files from a build context to an output directory.

    The vulnerability is that this function follows symbolic links by default.
    An attacker can place a symlink in the `build_context_dir` pointing to a
    sensitive file anywhere on the build host's filesystem. This process will
    dereference the symlink and copy the contents of the sensitive file into
    the final build artifact located in `output_dir`.
    """
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    for file_or_dir_name in os.listdir(build_context_dir):
        source_path = os.path.join(build_context_dir, file_or_dir_name)

        # The vulnerable action: shutil.copy() by default has `follow_symlinks=True`.
        # This means if `source_path` is a symlink to a file like '/etc/shadow'
        # or '~/.aws/credentials', the contents of that external file will be
        # copied into the output directory, not the symlink itself.
        try:
            shutil.copy(source_path, output_dir)
        except Exception:
            # In a real application, this might be more complex, but the core
            # copy operation is the source of the issue.
            pass

Patched code sample

import os
import shutil
import typing as t

def _ignore_symlinks(path: str, names: t.List[str]) -> t.List[str]:
    """
    An ignore pattern for shutil.copytree that ignores symlinks. This is the
    core of the fix for CVE-2024-40610 (user-provided CVE was a typo).

    For each directory being copied, this function is called. It checks if
    any of the items ('names') in the current directory ('path') are
    symbolic links. If an item is a symlink, its name is added to a list of
    items to be ignored by the copy operation.
    """
    ignored_names = []
    for name in names:
        # Construct the full path to the item
        item_path = os.path.join(path, name)
        # If the item is a symbolic link, add it to the ignore list
        if os.path.islink(item_path):
            ignored_names.append(name)
    return ignored_names

def fixed_copy_from_build_context(source_dir: str, destination_dir: str):
    """
    This function demonstrates the patched file copying mechanism.

    The vulnerable behavior resulted from shutil.copytree's default action,
    which is to follow symlinks and copy the contents of the file they point to.

    The fix is to provide the `ignore` argument to shutil.copytree, passing
    the `_ignore_symlinks` function. This prevents symlinks from being
    followed, thus stopping the file-exfiltration vulnerability.
    """
    shutil.copytree(
        source_dir,
        destination_dir,
        dirs_exist_ok=True,
        ignore=_ignore_symlinks,
    )

Payload

ln -s ~/.ssh/id_rsa ssh_key_leak

Cite this entry

@misc{vaitp:cve202640610,
  title        = {{BentoML follows symlinks during build, leaking host files into the Bento.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-40610},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-40610/}}
}
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 ::