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 ,
Comments
No comments yet. Start the discussion.