LangChain y LangGraph se han consolidado como los frameworks de referencia para construir aplicaciones LLM en producción. Chatbots corporativos, asistentes RAG, agentes autónomos que orquestan APIs internas, copilotos verticales: detrás de la mayoría de estos despliegues hay código LangChain en Python o JavaScript, o bien grafos de estado de LangGraph cuando el flujo deja de ser una cadena lineal y requiere ciclos, ramas o coordinación multi-agente.
Esa flexibilidad tiene contrapartida. LangChain expone primitivas que combinan ejecución de código, llamadas a herramientas privilegiadas, deserialización de objetos arbitrarios y memoria persistente respaldada por bases de datos. Patrones de ejemplo que aparecen en tutoriales y notebooks acaban en producción sin pasar por un threat model serio. El resultado: superficie de ataque híbrida entre código glue tradicional, capa LLM con prompt injection latente y herramientas con permisos amplios.
Esta guía recorre los riesgos específicos de LangChain y LangGraph, repasa CVEs históricas reales del framework, identifica patrones inseguros recurrentes en el código de equipos de producto y propone un esquema de hardening aplicable a despliegues actuales.
Lo esencial: LangChain acumula CVEs de ejecución de código, SQL injection y deserialización insegura por componentes diseñados para máxima flexibilidad (PythonREPLTool, SQLDatabaseChain, load_prompt, ConfigurableField). Los riesgos arquitectónicos como excessive agency, indirect prompt injection vía tool output y memory poisoning son tan críticos como los CVEs individuales. El hardening pasa por sandboxing de ejecución, allowlists estrictas en herramientas, validación Pydantic en inputs y outputs, eliminación total de pickle como formato de persistencia y human-in-the-loop en mutaciones sensibles.
LangChain y LangGraph en 60 segundos
LangChain abstrae la construcción de aplicaciones LLM en piezas reutilizables. Chains encadenan llamadas al modelo con pre y post procesamiento. Agents delegan en el LLM la decisión sobre qué herramienta invocar en cada paso. Tools son funciones que el agente puede ejecutar (consultar una API, buscar en una base de datos, lanzar código Python). Memory persiste contexto conversacional entre turnos. Retrievers alimentan al modelo con documentos relevantes en patrones RAG. Callbacks observan el ciclo de vida de cada invocación.
LangGraph nace como evolución para flujos que LangChain expresa con dificultad: workflows con estado explícito, ciclos controlados, ramificación condicional, coordinación entre varios agentes. Modela la aplicación como un grafo donde cada nodo es una función que lee y escribe sobre un objeto de estado compartido, con persistencia opcional vía checkpointers (memoria en memoria, SQLite, Postgres, Redis).
La adopción es masiva. La consecuencia: cualquier hallazgo de seguridad sobre estos frameworks tiene impacto inmediato sobre miles de aplicaciones en producción.
Por qué LangChain merece auditoría dedicada
Una aplicación LangChain típica integra tres capas con modelos de amenazas distintos: código Python o JavaScript convencional con sus vulnerabilidades clásicas (inyección, deserialización, path traversal), capa LLM con prompt injection y manipulación de salidas, y herramientas que el agente invoca con permisos heredados del proceso.
La auditoría tradicional de aplicaciones cubre la primera capa. El pentesting de LLM aborda la segunda. Lo que diferencia a LangChain es la frontera entre las tres: una herramienta puede recibir input directamente del LLM, que a su vez procesa contenido externo no confiable, mientras se ejecuta con privilegios de servicio. Esa cadena rompe asunciones habituales sobre validación de entrada y separación de privilegios.
Auditar LangChain exige revisión simultánea de código, análisis del grafo de tools y prompts, y pruebas adversariales sobre el flujo completo. Pocas metodologías estándar lo cubren de forma integral.
Vulnerabilidades CVE históricas LangChain
El historial público de CVEs sobre LangChain ilustra el patrón: ejecución de código a través de herramientas pensadas para máxima funcionalidad, inyección SQL en chains que generan consultas, deserialización insegura en componentes de carga.
CVE-2023-29374 afecta a PALChain, un componente que permitía al LLM generar y ejecutar código Python para resolver problemas matemáticos. Un atacante con control sobre la entrada al chain podía conseguir ejecución arbitraria de código en el proceso anfitrión. La mitigación oficial supuso quitar el componente del flujo por defecto.
CVE-2023-32785 alcanza a SQLDatabaseChain, cadena que traduce lenguaje natural a SQL contra bases de datos relacionales. Generaba consultas sin protección suficiente, abriendo vectores de inyección SQL clásicos cuando el atacante podía manipular el prompt de entrada.
CVE-2023-39659 agrupa varios issues de deserialización en componentes que cargaban objetos serializados (pickle, principalmente) desde rutas controladas externamente. Pickle permite ejecución de código durante la deserialización, así que cualquier carga de archivo no confiable se traduce en RCE.
CVE-2024-2057 corresponde a load_prompt(), función de utilidad que cargaba plantillas de prompt desde rutas locales o remotas. Permitía path traversal y acceso a archivos fuera del directorio previsto cuando la ruta llegaba desde input no validado.
CVE-2024-21513 afecta a ConfigurableField dentro de LCEL (LangChain Expression Language). Permitía deserialización insegura cuando se cargaban configuraciones de campos dinámicos desde fuentes externas, replicando el problema base de pickle en una abstracción nueva.
El patrón es claro: el framework prioriza flexibilidad sobre seguridad por defecto. Cada vez que aparece una abstracción nueva con capacidad de cargar código, configuración o consultas desde fuentes externas, reaparece el mismo tipo de vulnerabilidad.
Patrones inseguros comunes en código LangChain
Más allá de los CVEs publicados, la mayor superficie de riesgo está en código de aplicación que sigue patrones inseguros heredados de tutoriales y ejemplos oficiales.
PythonREPLTool sin sandbox es el caso más extendido. Equipos exponen al agente la capacidad de ejecutar Python arbitrario en el mismo proceso, asumiendo que el LLM solo escribirá código benigno. Una prompt injection bien construida convierte esa herramienta en RCE inmediato sobre la máquina anfitriona, con acceso al filesystem, variables de entorno y servicios accesibles desde la red interna.
ShellTool sin allowlist replica el problema en capa de sistema. La herramienta ejecuta comandos shell sin filtrado; cualquier instrucción del LLM se traduce en proceso hijo con los privilegios del servicio.
load_prompt() con archivos externos persiste como antipatrón incluso tras CVE-2024-2057, cuando equipos cargan prompts desde rutas construidas dinámicamente sin validar el origen.
Pickle y cloudpickle para chains guardados aparece en flujos donde los equipos serializan agentes completos o chains complejos para reutilizarlos. Cualquier archivo pickle cargado desde fuente no confiable es ejecución de código garantizada.
eval() en custom output parsers se cuela cuando un desarrollador necesita interpretar la salida del LLM como expresión Python o JavaScript. Si la respuesta del modelo contiene contenido manipulado, eval lo ejecuta tal cual.
Agent con tools demasiado privilegiados abarca casos como un agente con acceso a la API de administración interna, capacidad de modificar bases de datos sin filtrado o invocación de servicios cloud con credenciales amplias. La excessive agency es difícil de medir sin mapeo explícito de capacidades.
Memory backed by SQL sin sanitización aparece cuando se persiste historial conversacional en bases de datos relacionales y la query de recuperación interpola directamente identificadores controlados por el usuario. Replica vectores clásicos de SQL injection.
Riesgos arquitectónicos
Por encima de los patrones de código existen riesgos estructurales que no se resuelven parcheando una línea concreta.
Indirect prompt injection vía tool output ocurre cuando una herramienta devuelve contenido que entra al contexto del LLM sin segregación. Si el agente consulta una página web, lee correos o accede a una base de datos donde un atacante ha sembrado instrucciones, el modelo trata ese contenido como input legítimo. La instrucción inyectada puede orientar al agente a invocar otras herramientas, exfiltrar datos o modificar su comportamiento.
Excessive agency se manifiesta cuando el agente tiene capacidad para ejecutar acciones cuyo impacto excede el valor de la tarea. Acceso a producción, escritura sobre sistemas críticos, capacidad de enviar comunicaciones externas: cualquier herramienta que produzca efectos persistentes merece evaluación específica.
Memory poisoning afecta a despliegues con memoria persistente (Redis, SQL, vector stores). Si un atacante consigue escribir en la memoria de una sesión o conversación de otro usuario, puede manipular el comportamiento futuro del agente sin volver a inyectar nada. Es particularmente crítico en escenarios multi-tenant.
Callback handlers como vector de exfiltración aparece cuando se registran callbacks que envían trazas a sistemas externos (LangSmith, observabilidad propia, logging remoto). Si la traza incluye contenido sensible y el endpoint de destino es manipulable, el callback se convierte en canal de salida.
Hardening específico LangChain y LangGraph
El esquema defensivo cubre varias dimensiones simultáneamente.
Reemplazar PythonREPLTool por sandbox Docker mediante servicios tipo e2b, sandboxes propios o contenedores efímeros con red restringida. La ejecución de código generado por LLM nunca debería compartir proceso con la aplicación principal.
ShellTool con allowlist de comandos limita la herramienta a un conjunto cerrado de utilidades verificadas. Cualquier comando fuera de la lista se rechaza antes de invocar el subproceso.
Persistencia de chains vía JSON safe, eliminando pickle y cloudpickle del flujo. LangChain ofrece serialización JSON para la mayoría de componentes; donde no llega, conviene reconstruir el chain en código en lugar de cargar binarios opacos.
Validación de input de tools con esquemas Pydantic estrictos convierte cada herramienta en una función con contrato verificable. El agente solo puede invocarla con argumentos que cumplen el esquema; cualquier desviación se rechaza antes de tocar la lógica.
Human-in-the-loop en mutaciones críticas introduce un paso de aprobación humana antes de ejecutar acciones de alto impacto: envío de correos, modificaciones en producción, transferencias, cambios de configuración. LangGraph lo soporta nativamente con nodos de interrupción.
Output validators con JSON schema verifican que la salida del modelo cumple el formato esperado antes de pasarla al siguiente paso. Reduce el riesgo de inyectar contenido manipulado en componentes downstream.
Memory isolation per session garantiza que la memoria de una conversación nunca se cruza con la de otra. Claves de partición explícitas, validación del propietario de la sesión y separación física cuando el modelo de amenaza lo justifica.
Rate limit y cost ceiling protegen tanto frente a abuso como frente a bucles del propio agente. Un agente con bug puede generar cientos de llamadas en segundos; el límite evita que el incidente escale.
Audit log con trazas completas registra cada paso del agente: prompt enviado al modelo, herramienta invocada, argumentos, respuesta. Es la base para investigación post incidente y para detectar patrones anómalos en tiempo real.
Auditoría de aplicación LangChain
La metodología de auditoría combina cuatro frentes.
Code review estructurado sobre el repositorio de la aplicación: localizar todas las definiciones de tools, mapear los permisos heredados, identificar uso de PythonREPLTool, ShellTool, pickle, eval, load_prompt y cualquier punto donde input externo alimente al agente. La revisión también cubre la configuración de memoria, callbacks y serialización.
Runtime testing sobre la aplicación desplegada en un entorno de prueba representativo. Reproducción de los flujos legítimos del agente y observación del trace para verificar que el comportamiento esperado coincide con el real.
Prompt injection adversarial con un catálogo de payloads orientados a desbloquear herramientas restringidas, escapar del system prompt, manipular la memoria y inducir excessive agency. Las pruebas deben cubrir tanto inyección directa por el usuario como indirecta a través de contenido recuperado por retrievers o devuelto por tools.
Tool abuse scenarios simula que el atacante ya consiguió control sobre la salida del LLM y prueba el impacto real de cada tool en condiciones controladas. Es la única forma de medir cuánto daño puede causar un agente comprometido y de identificar herramientas que sobran o que requieren refuerzo.
LangGraph specifics
LangGraph introduce primitivas adicionales que merecen análisis propio.
El state graph se convierte en superficie de análisis. Cada nodo lee y escribe sobre el objeto de estado compartido; la auditoría debe verificar que un nodo comprometido no puede corromper estado leído por nodos posteriores con permisos diferentes. El esquema del estado conviene definirlo con Pydantic y validar invariantes en transiciones críticas.
Checkpointing security afecta a la persistencia del estado entre invocaciones. Si el checkpointer usa Redis, SQL o filesystem, hereda los riesgos del backend: control de acceso, cifrado, aislamiento entre sesiones. Cargar un checkpoint manipulado puede reanudar el grafo en un estado que viola asunciones del código.
Multi-agent risks aparecen en grafos donde varios agentes colaboran. Un agente comprometido puede manipular el estado compartido para influir en decisiones de otros agentes. El threat model debe considerar al conjunto, no a cada agente por separado.
Preguntas frecuentes
¿LangChain es seguro para producción?
LangChain puede usarse en producción con un perfil de seguridad aceptable siempre que se eliminen los patrones inseguros documentados, se mantenga al día con las versiones que cierran CVEs y se aplique un esquema de hardening específico al despliegue. No es un framework inseguro por diseño; sí es un framework que requiere decisiones explícitas en cada capa.
¿Usar PythonREPLTool nunca?
Nunca en el mismo proceso que la aplicación. Si la lógica de negocio requiere ejecución de código generado por el LLM, debe delegarse en una sandbox aislada (Docker, e2b, microVMs) con red restringida, sin acceso a credenciales del servicio principal y con timeout estricto.
¿Custom tools cómo auditar?
Cada custom tool merece revisión individual cubriendo: validación del input con esquema Pydantic, permisos efectivos de la función, side effects, manejo de errores que no filtre información interna, y comportamiento bajo input malicioso. El conjunto de tools de un agente debe pasar también por un análisis de excessive agency: qué impacto tiene un agente comprometido si encadena varias tools.
¿Memory backend recomendado?
Para producción, backends con control de acceso por sesión, aislamiento entre tenants y trazabilidad. Postgres con esquemas separados por tenant funciona en muchos casos. Redis es válido si se gestiona aislamiento explícito. Vector stores requieren atención adicional porque la semántica de "documento más cercano" puede cruzar fronteras de tenant si no se filtra correctamente.
¿Alternativas a LangChain más seguras?
No existe un sustituto directo con perfil de seguridad sustancialmente mejor; los riesgos son inherentes al modelo de aplicación LLM con tools y memoria, no al framework concreto. Alternativas como LlamaIndex, Haystack, frameworks propios o el SDK directo del proveedor comparten la mayoría de superficies. La decisión razonable es elegir según madurez, ecosistema y velocidad de adopción de parches.
¿Pentest LangChain cómo?
Combinando revisión de código, análisis del grafo de tools y prompts, pruebas adversariales de prompt injection directa e indirecta, escenarios de tool abuse y validación del hardening aplicado. La duración típica de una auditoría completa va de una a tres semanas según complejidad del despliegue.
Recursos relacionados
- Seguridad de agentes IA autónomos: riesgos
- OWASP LLM Top 10 explicado
- Qué es prompt injection: ataques LLM
- Seguridad RAG: retrieval augmented generation
- Pentesting de modelos IA y LLM: metodología
- AI red teaming: evaluación de modelos IA
Auditoría LangChain con Secra
En Secra auditamos aplicaciones construidas sobre LangChain y LangGraph combinando code review estructurado, pruebas de prompt injection adversarial sobre el flujo completo, escenarios de tool abuse y recomendaciones de hardening adaptadas al stack y al modelo de amenaza concreto del despliegue. Entregamos un informe técnico con hallazgos priorizados, prueba de concepto reproducible para cada vulnerabilidad confirmada y un plan de remediación accionable por el equipo de producto.
Si tu organización ha desplegado o está cerca de desplegar una aplicación LLM en producción, contacta con Secra para coordinar una auditoría específica.
Sobre el autor
Equipo de Secra Solutions
Ethical hackers certificados OSCP, OSEP, OSWE, CRTO, CRTL y CARTE, con más de 7 años de experiencia en ciberseguridad ofensiva. Autores de los CVE-2025-40652 y CVE-2023-3512.