CVE-2026-17633 - Authenticated RCE in Langflow OSS via /api/v1/custom_component
DEV Community

CVE-2026-17633 - Authenticated RCE in Langflow OSS via /api/v1/custom_component

Summary

Field Value
CVE ID CVE-2026-17633
CVSS 8.5 (HIGH)
CWE CWE-94 (Improper Control of Generation of Code)
Affected Langflow OSS 1.0.0 - 1.10.3
Preconditions Any authenticated user + LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true
Vulnerable endpoint POST /api/v1/custom_component

Overview

Langflow is an open-source low-code platform for building LLM applications and agent workflows visually. One of its features, Custom Components, lets users define a component's behavior directly in Python. That feature is the attack surface for this vulnerability. IBM's security advisory (published August 5, 2026) disclosed a cluster of issues in Langflow OSS 1.0.0-1.10.3. CVE-2026-17633 is the authenticated RCE reachable through /api/v1/custom_component.

Root Cause - Source-Level Analysis

1.1 The Vulnerable Endpoint

From langflow/api/v1/endpoints.py (around line 1271):

@router.post ( " /custom_component " , status_code = HTTPStatus . OK , include_in_schema = False )
async def custom_component ( raw_code : CustomComponentRequest , user : CurrentActiveUser , request : Request , ) -> CustomComponentResponse :
    …
    # The only gate: "is the custom-component feature enabled at all?"
    if not settings . allow_custom_components and not code_hash_matches_any_template ( raw_code . code , all_known ):
        raise HTTPException ( status_code = status . HTTP_403_FORBIDDEN , … )
    # scan_code_security() is never called here
    component = Component ( _code = effective_code )
    built_frontend_node, component_instance = build_custom_component_template ( component, user_id = user . id )

The important detail isn't that there's "no validation" - it's that the validation checks the wrong thing. allow_custom_components answers "is this user allowed to create custom components," not "is this code's content safe." In production, LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true is a common setting, and once it's on, this check passes trivially and the code flows through with zero content inspection. Langflow does ship a separate AST-based scanner, scan_code_security() (covered in section 5), but this endpoint's execution path never calls it.

1.2 The Actual Bug Lives in prepare_global_scope()

custom_component() calls build_custom_component_template(), which flows into create_class() in lfx/custom/validate.py. That function calls prepare_global_scope(), and the submitted code is exec()'d shortly after.

def prepare_global_scope ( module ):
    exec_globals = globals (). copy ()
    …
    for node in module . body :
        if isinstance ( node , ast . Import | ast . ImportFrom ):
            imports . append ( node )
        elif isinstance ( node , ast . ClassDef | ast . FunctionDef | ast . Assign | ast . AnnAssign ):
            definitions . append ( node )
        …
    if definitions :
        compiled_code = compile ( combined_module , " <string> " , " exec " )
        exec ( compiled_code ,
Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.