FlawOpen

flawopen.com/Teardowns/cve-2026-5027-langflow-multipart-file-write

● CVE-2026-5027 · CVSS 8.8[1], [2] · High
FlawOpen Security Research

Langflow CVE-2026-5027: Multipart File-Write Path Traversal

CVE-2026-5027 enabled file writes beyond Langflow’s upload area via path traversal. GTIG reports exploitation; upgrade to 1.9.0 or later.[1], [2], [6]

CVSS vectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H[1], [2]
💡 Plain English Explainer (ELI5)

A mailroom accepts a parcel whose sender can choose both its label and destination. If the clerk joins that label to the mailroom folder without checking the final address, the parcel can be filed outside the mailroom. Langflow’s upload route trusted the multipart filename, while its storage layer did not independently prove the final path stayed inside the upload root.[2], [3]

Core Concepts & Subsystem Terms

CVE-2026-5027
Tenable-assigned identifier for a Langflow path traversal in the POST /api/v2/files multipart filename, tracked as CWE-22 and scored CVSS 3.1 8.8 with low privileges required.[1], [2]
Multipart filename
The client-supplied filename in a multipart upload’s Content-Disposition header. It is untrusted input, not a safe filesystem path.[1], [2]
Path containment
A check that resolves the candidate path and proves it remains beneath an approved storage directory before creating or writing files.[3], [4], [7]
Identifier note
Langflow’s related GitHub advisory for the multipart upload issue lists CVE-2026-33309, while Tenable and Google GTIG use CVE-2026-5027. This page follows GTIG’s identifier and preserves both records in its sources rather than silently merging their metadata.[4], [5], [6]

Framework mappings

  • CWE reference for the weakness described in this guide: CWE-22

Root Cause Analysis

Tenable’s CVE-2026-5027 record describes POST /api/v2/files accepting a multipart filename containing traversal components and writing outside the intended directory. The relevant security boundary spans the API route and local storage: validating URL path parameters does not validate a filename read from multipart Content-Disposition, and joining an unchecked name to a storage folder does not establish containment. The CVE record rates the issue High, CVSS 3.1 8.8, CWE-22, with PR:L; describe it as authenticated file write. Do not claim that the CVE itself bypasses authentication. Google Threat Intelligence Group lists CVE-2026-5027 among confirmed in-the-wild exploited vulnerabilities, but its public summary does not establish a universal code-execution outcome. Arbitrary file write can create more severe consequences depending on writable paths, process privileges, and deployment configuration; treat those as conditional impact, not as guaranteed RCE. Langflow’s related GHSA for the multipart upload flaw lists CVE-2026-33309 and also points to the 1.9.0 fix. This article follows CVE-2026-5027 as named by Tenable and GTIG and keeps the identifier discrepancy explicit. The merged Langflow patch validates filenames at the API layer and enforces canonical path containment at the storage layer, including before directory creation.[1], [2], [3], [4], [5], [6]

Step-by-Step Attack Flow

Step 1

A low-privilege caller reaches the upload API

The CVE-2026-5027 CVSS vector requires low privileges. The relevant path is POST /api/v2/files; the record does not establish an authentication bypass.[1], [2]

Step 2

The request supplies a multipart filename

The upload filename comes from client-controlled Content-Disposition metadata. URL parameter validation does not sanitize this independent input source.[1], [2], [4]

Step 3

The vulnerable path crosses the storage boundary

If the application combines the untrusted name with its upload folder without canonical containment validation, traversal components can resolve outside that folder.[1], [2], [3], [7]

Step 4

An out-of-root file is written

The documented impact is arbitrary file write. Code execution or persistence depends on whether the service identity can write to a consequential location and how the deployment handles that file; do not assume every upload yields RCE.[1], [2], [6]

Step 5

Patch both validation boundaries

Langflow merged API filename checks and storage-layer canonical containment into the 1.9.0 release line. Upgrade and verify the resolved packages and running image.[2], [3], [4]

Source Code: Flaw vs. Secure Implementation

These are reduced, source-shaped examples, not a verbatim upstream diff. The vulnerable path treats the client filename as a storage path. The hardened pattern validates the leaf name and then checks the canonical destination against the canonical root at the storage boundary; the upstream PR also rejects separators and control characters and validates containment before directory creation. Keep the storage check even if the HTTP layer validates input, because other callers may bypass the route. The sample assumes a supported Python version with Path.is_relative_to and does not by itself eliminate filesystem time-of-check/time-of-use races in hostile writable directories; production storage should use race-resistant directory/file operations and restrictive permissions. The mitigation is path confinement, not a filename blacklist alone.[3], [2], [4], [7]

Source excerpt: Langflow api/v2/files.py and services/storage/local.py — reduced security-boundary example

UNPATCHED FLAW
# Reduced example of the vulnerable data flow.
new_filename = file.filename
file_path = folder_path / new_filename
await write_upload(file, file_path)
HARDENED SECURE PATCH
from pathlib import Path

def confined_upload_path(root: Path, client_name: str | None) -> Path:
    name = Path(client_name or "").name
    if not name or name in {".", ".."} or chr(0) in name:
        raise ValueError("invalid upload filename")

    base = root.resolve()
    target = (base / name).resolve()
    if not target.is_relative_to(base):
        raise ValueError("upload path escapes storage root")
    return target

# Call this at the storage boundary immediately before creating or writing.
target = confined_upload_path(upload_root, file.filename)
await write_upload(file, target)

Engineering & System Hardening Checklist

Sources