VAITP Dataset

← Back to the dataset

CVE-2026-48776

Unsafe URL path construction in LangGraph SDK allows for path traversal.

  • CVSS 9.1
  • CWE-22
  • Input Validation and Sanitization
  • Remote

LangGraph Python SDK is used to connect to running LangGraph API servers, manage assistants, threads and stream runs from Python applications. Versions 0.3.14 and prior have unsafe URL path construction through unsanitized caller-supplied identifier values used in HTTP request paths for resource operations. Without sanitization of those values, identifiers that contain characters with special meaning in URL paths could cause the resulting request to address a different resource (and potentially a different resource type) than the SDK method's call site indicates. In deployments where the SDK receives identifier values that originate from untrusted sources, this could result in unintended access, modification, or deletion of resources beyond the calling user's authorization scope. This issue is most consequential in deployments that forward end-user-supplied values directly into SDK identifier parameters without first validating them against an expected format (such as a UUID), and rely on URL-prefix-based authorization at an upstream layer (reverse proxy, edge gateway, WAF), where the authorization decision is made on the SDK call's intended path rather than on the final delivered request path. The issue has been fixed in version 0.3.15.

CVSS base score
9.1
Published
2026-06-17
OWASP
A01 Broken Access Control
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Path Traversal
Accessibility scope
Remote
Impact
Unauthorized Access
Affected component
LangGraph Py
Fixed by upgrading
Yes

Solution

Upgrade to LangGraph Python SDK version 0.3.15 or later.

Vulnerable code sample

import os

class VulnerableClient:
    """
    A simplified, conceptual client representing the behavior of
    LangGraph SDK versions 0.3.14 and prior. This is for demonstration only.
    """
    def __init__(self, base_url: str):
        self.base_url = base_url.rstrip('/')

    def _make_request(self, method: str, path: str):
        # In a real SDK, this would use a library like 'requests' or 'httpx'.
        # For this example, we resolve the path and print the final URL
        # to show what the server would receive.
        final_url = os.path.normpath(os.path.join(self.base_url, path))
        print(f"Making {method} request to: {final_url}")

    def delete_thread(self, thread_id: str):
        """
        Constructs a URL to delete a thread. This method is vulnerable
        because it does not sanitize the user-provided 'thread_id'.
        """
        # VULNERABLE CODE: The thread_id is used directly in the path.
        path = f"/threads/{thread_id}"
        self._make_request("DELETE", path)

# --- Demonstration of the vulnerability ---

# Assume the SDK is used to connect to an API at this base URL.
# A reverse proxy might be configured to only allow the user access to
# paths starting with '/threads/'.
client = VulnerableClient("https://api.example.com")

# 1. An attacker provides a crafted identifier.
# Instead of being a simple UUID, it contains path traversal characters.
malicious_thread_id = "ignored_id/../../admin/delete_project/123"

# 2. The developer, unaware, passes the untrusted input directly to the SDK.
# The intended operation is to delete a thread within the user's scope.
print(f"Calling delete_thread with malicious ID: '{malicious_thread_id}'")

# 3. The vulnerable SDK constructs a malicious path.
# The final request targets a different, unauthorized endpoint.
client.delete_thread(malicious_thread_id)

Patched code sample

import urllib.parse

def build_safe_request_path(base_path: str, resource_id: str) -> str:
    """
    Represents the fixed method for constructing a safe URL path.

    The vulnerability is fixed by sanitizing the user-supplied resource
    identifier before it is appended to the URL path. This is done by
    URL-encoding the identifier, which ensures that special characters
    (like '/', '.', etc.) are treated as part of the identifier string
    rather than as URL path delimiters.
    """
    # The fix: The untrusted identifier is URL-encoded.
    # The `safe=''` argument is critical as it ensures that path
    # separator characters like '/' are also encoded, which prevents
    # path traversal.
    safe_resource_id = urllib.parse.quote(resource_id, safe='')

    # The sanitized identifier is then safely joined to the base path.
    return f"{base_path}/{safe_resource_id}"

# Example demonstrating the fix:

# A malicious identifier attempting path traversal to access a different resource type.
# The user-supplied value is 'asst_123/../threads'
malicious_id = "asst_123/../threads"
base_api_path = "/v1/assistants"

# The vulnerable approach would have been:
# vulnerable_path = f"{base_api_path}/{malicious_id}"
# This would incorrectly resolve to "/v1/threads"

# The fixed approach correctly sanitizes the ID:
fixed_path = build_safe_request_path(base_api_path, malicious_id)

# The resulting path correctly keeps the malicious payload as part of the
# identifier, which will almost certainly result in a 404 Not Found,
# thereby preventing the unauthorized access.
# Expected output: /v1/assistants/asst_123%2F..%2Fthreads
print(fixed_path)

Payload

malicious_identifier = "../another-assistant-id"

Cite this entry

@misc{vaitp:cve202648776,
  title        = {{Unsafe URL path construction in LangGraph SDK allows for path traversal.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-48776},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-48776/}}
}
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 ::