LangChain CVE-2025-68664: Cómo los datos personales filtran desde su pipeline RAG
Actualizado para 2026.
Se descubrió una falla crítica en LangChain a finales de 2025. El CVE es CVE-2025-68664. La puntuación CVSS es 9.3 (Crítico).
Afecta el código de serialización de LangChain.
Qué hace CVE-2025-68664
LangChain tiene dos funciones de serialización: dumps() y dumpd(). Convierten objetos de Python en texto.
La falla está en el manejo de closures.
Cuando LangChain serializa un callable, captura el contexto del closure.
Un atacante que controla la respuesta del LLM puede activar dumps(). La función entonces lee variables de entorno del proceso de Python.
El resultado es una exposición de datos. Claves API, cadenas de conexión a bases de datos, secretos JWT y credenciales de AWS pueden aparecer en la salida del modelo.
Un atacante que inyecta texto en un documento fuente RAG puede leer sus secretos de producción.
Versiones afectadas: LangChain inferior a 0.3.22 (Python). La versión 0.3.22 contiene el parche.
Los datos de PyPI muestran un uso generalizado de versiones antiguas hasta marzo de 2026.
Cómo filtran los datos personales en los pipelines RAG
CVE-2025-68664 es un caso extremo de un problema más amplio.
Los datos filtran rutinariamente por los pipelines RAG. No se necesita ningún atacante.
Aquí está una configuración RAG empresarial estándar.
Primero, la ingesta. Indexa documentos de la empresa en un almacén vectorial. Piense en tickets de soporte, correos de clientes, contratos y registros de RRHH.
Los almacenes vectoriales más comunes son Pinecone, Weaviate y pgvector.
Segundo, la recuperación. Un usuario hace una pregunta. El sistema extrae los cinco fragmentos más relevantes.
Tercero, la generación. Esos fragmentos se envían a un LLM — GPT-4o, Claude o Gemini — como contexto.
El paso dos es el problema. Los fragmentos recuperados contienen todo lo que tenían los documentos fuente. Eso incluye:
- Nombres de clientes, direcciones de correo y números de teléfono
- Valores de contratos, números de cuenta e identificadores fiscales
- Datos salariales y notas de evaluación de empleados
- Nombres de pacientes en notas clínicas
- Números de identificación nacional en archivos de inmigración
Esos datos se envían al LLM tal cual. Pueden aparecer en la salida del modelo.
Son registrados por el proveedor del LLM. Se almacenan en su historial de conversación. Fluyen hacia su stack de observabilidad.
No se necesita ningún ataque. Así funciona RAG por diseño. Este diseño crea un riesgo real para la privacidad.
68 patrones de secretos en documentos empresariales
Las herramientas de seguridad rastrean 68 patrones de secretos conocidos. Aparecen más a menudo de lo que los equipos esperan.
Aquí están los más comunes.
- AWS Access Key IDs (
AKIA...) - Claves API de OpenAI (
sk-...) - Claves API de Anthropic (
sk-ant-...) - URIs de base de datos (
postgresql://user:password@host/db) - Tokens JWT (encabezados codificados en base64)
- GitHub Personal Access Tokens
- Claves secretas de Stripe (
sk_live_...) - Claves API de SendGrid
- SIDs de cuenta de Twilio y tokens de autenticación
- Bloques PEM de clave privada
Un ticket de soporte puede contener una clave API de un cliente de una sesión de depuración.
Un contrato puede incluir credenciales de base de datos de una transferencia técnica.
Un archivo de configuración indexado por error puede exponer un almacén completo de secretos.
Cuando estos archivos entran en un almacén vectorial sin saneamiento, cada consulta puede pasar los secretos al LLM.
También pueden llegar al usuario final.
La solución: anonimizar antes de embeber
El enfoque correcto anonimiza los documentos antes del chunking y el embedding.
Este paso es obligatorio para cualquier sistema que maneje datos de clientes.
Aquí hay un ejemplo de Python usando la API de anonym.legal:
import requests
import os
ANONYM_API_KEY = os.environ["ANONYM_API_KEY"]
ANONYM_BASE_URL = "https://anonym.legal/api"
def anonymize_before_embedding(text: str) -> tuple[str, dict]:
"""Anonimizar datos personales antes del embedding."""
response = requests.post(
f"{ANONYM_BASE_URL}/presidio/anonymize",
json={
"text": text,
"language": "en",
"anonymizers": {
"DEFAULT": {"type": "replace", "new_value": "[REDACTED]"},
"PERSON": {"type": "mask", "masking_char": "*", "chars_to_mask": 4, "from_end": False},
"EMAIL_ADDRESS": {"type": "replace", "new_value": "[EMAIL]"},
"PHONE_NUMBER": {"type": "replace", "new_value": "[PHONE]"},
"CRYPTO": {"type": "replace", "new_value": "[SECRET]"},
"URL": {"type": "keep"},
}
},
headers={"Authorization": f"Bearer {ANONYM_API_KEY}"}
)
result = response.json()
return result["text"], result.get("items", [])
def build_rag_index(documents: list[str], vectorstore):
"""Construir un índice RAG solo con documentos limpios."""
anonymized_docs = []
for doc in documents:
clean_text, entities = anonymize_before_embedding(doc)
anonymized_docs.append(clean_text)
print(f"Removed {len(entities)} PII entities from document")
vectorstore.add_texts(anonymized_docs)
La API de anonym.legal cubre más de 285 tipos de entidades. Nombres, correos, teléfonos, identificadores nacionales, claves API y URIs de bases de datos son todos detectados.
Ningún dato sensible llega al almacén vectorial. Por tanto, ningún dato sensible puede filtrarse a los usuarios.
Consulte la guía para desarrolladores para patrones de integración con LangChain y LlamaIndex.
Corrija CVE-2025-68664 ahora mismo
Si usa LangChain inferior a 0.3.22, actualice ahora:
pip install "langchain>=0.3.22" "langchain-core>=0.3.22"
Tras el parche, revise sus configuraciones de cadena para detectar riesgos de inyección. Aquí hay tres pasos.
Primero, valide los fragmentos recuperados. Hágalo antes de que lleguen al LLM.
Elimine el contenido que coincida con patrones de inyección como ignore previous instructions, system: o <INST>.
Segundo, anonimice antes de embeber. Esto reduce la superficie de ataque.
Si ocurre una inyección, los datos sensibles ya no están presentes para ser extraídos.
Tercero, restrinja los permisos de la cadena. Las cadenas de LangChain no deben leer más variables de entorno de las necesarias.
Use una cuenta de servicio con alcance mínimo.
La matemática es simple
La puntuación CVSS es 9.3. El parche es una llamada API por documento.
La combinación de CVE-2025-68664 y el riesgo general de datos RAG es una responsabilidad real.
La solución es clara: anonimizar en la ingesta, no en el momento de la consulta.
Consulte la visión general de seguridad y cumplimiento para los requisitos RAG empresariales.
Fuentes
- NVD CVE-2025-68664, CVSS 9.3, vulnerabilidad de serialización de LangChain
- Aviso de seguridad de LangChain, langchain-ai/langchain GitHub, 2025
- OWASP LLM Top 10: LLM01 Inyección de prompt, LLM06 Divulgación de información sensible
- Documentación de tipos de entidad de anonym.legal — más de 285 tipos admitidos