LangChain CVE-2025-68664 : Comment les données personnelles fuient de votre pipeline RAG
Mis à jour pour 2026.
Une faille critique a été découverte dans LangChain fin 2025. La CVE est CVE-2025-68664. Le score CVSS est 9.3 (Critique).
Elle cible le code de sérialisation de LangChain.
Ce que fait CVE-2025-68664
LangChain dispose de deux fonctions de sérialisation : dumps() et dumpd(). Elles convertissent des objets Python en texte.
La faille se situe dans la gestion des fermetures (closures).
Lorsque LangChain sérialise un callable, il capture le contexte de la fermeture.
Un attaquant qui contrôle la réponse du LLM peut déclencher dumps(). La fonction lit alors les variables d'environnement du processus Python.
Le résultat est une exposition de données. Les clés API, les chaînes de connexion à la base de données, les secrets JWT et les identifiants AWS peuvent apparaître dans la sortie du modèle.
Un attaquant qui injecte du texte dans un document source RAG peut lire vos secrets de production.
Versions concernées : LangChain en dessous de 0.3.22 (Python). La version 0.3.22 contient le correctif.
Les données PyPI montrent une utilisation étendue des versions anciennes jusqu'en mars 2026.
Comment les données personnelles fuient dans les pipelines RAG
CVE-2025-68664 est un cas extrême d'un problème plus large.
Les données fuient régulièrement des pipelines RAG. Aucun attaquant n'est nécessaire.
Voici une configuration RAG d'entreprise standard.
Premièrement, l'ingestion. Vous indexez des documents d'entreprise dans un magasin vectoriel. Pensez aux tickets de support, aux e-mails clients, aux contrats et aux dossiers RH.
Les magasins vectoriels courants sont Pinecone, Weaviate et pgvector.
Deuxièmement, la récupération. Un utilisateur pose une question. Le système extrait les cinq fragments les plus pertinents.
Troisièmement, la génération. Ces fragments sont transmis à un LLM — GPT-4o, Claude ou Gemini — en tant que contexte.
L'étape deux est le problème. Les fragments récupérés contiennent tout ce que les documents sources contenaient. Cela inclut :
- Les noms de clients, adresses e-mail et numéros de téléphone
- Les valeurs contractuelles, numéros de compte et identifiants fiscaux
- Les données salariales et notes d'évaluation des employés
- Les noms de patients dans les notes cliniques
- Les numéros d'identification nationale dans les dossiers d'immigration
Ces données parviennent au LLM telles quelles. Elles peuvent apparaître dans la sortie du modèle.
Elles sont enregistrées par le fournisseur LLM. Elles restent dans votre historique de conversation. Elles circulent dans votre pile d'observabilité.
Aucune attaque n'est nécessaire. C'est ainsi que fonctionne RAG par conception. Cette conception crée un vrai risque pour la vie privée.
68 modèles de secrets dans les documents d'entreprise
Les outils de sécurité suivent 68 modèles de secrets connus. Ils apparaissent plus souvent que les équipes ne l'espèrent.
Voici les plus courants.
- AWS Access Key IDs (
AKIA...) - Clés API OpenAI (
sk-...) - Clés API Anthropic (
sk-ant-...) - URIs de base de données (
postgresql://user:password@host/db) - Tokens JWT (en-têtes encodés en base64)
- GitHub Personal Access Tokens
- Clés secrètes Stripe (
sk_live_...) - Clés API SendGrid
- SID de compte Twilio et tokens d'authentification
- Blocs PEM de clé privée
Un ticket de support peut contenir une clé API client d'une session de débogage.
Un contrat peut inclure des identifiants de base de données issus d'un transfert technique.
Un fichier de configuration indexé par erreur peut exposer un magasin de secrets entier.
Lorsque ces fichiers entrent dans un magasin vectoriel sans nettoyage, chaque requête peut transmettre les secrets au LLM.
Ils peuvent aussi atteindre l'utilisateur final.
La solution : anonymiser avant l'embedding
La bonne approche anonymise les documents avant le découpage et l'embedding.
Cette étape est obligatoire pour tout système qui traite des données clients.
Voici un exemple Python utilisant l'API 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]:
"""Anonymiser les données personnelles avant l'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):
"""Construire un index RAG uniquement avec des documents propres."""
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)
L'API anonym.legal couvre plus de 285 types d'entités. Les noms, e-mails, numéros de téléphone, identifiants nationaux, clés API et URIs de base de données sont tous détectés.
Aucune donnée sensible n'atteint le magasin vectoriel. Rien de sensible ne peut donc fuir vers les utilisateurs.
Consultez le guide développeur pour les modèles d'intégration LangChain et LlamaIndex.
Corriger CVE-2025-68664 maintenant
Si vous utilisez LangChain en dessous de 0.3.22, mettez à jour maintenant :
pip install "langchain>=0.3.22" "langchain-core>=0.3.22"
Après le correctif, vérifiez vos configurations de chaîne pour les risques d'injection. Voici trois étapes.
Premièrement, validez les fragments récupérés. Faites-le avant qu'ils n'atteignent le LLM.
Supprimez le contenu qui correspond aux motifs d'injection comme ignore previous instructions, system: ou <INST>.
Deuxièmement, anonymisez avant l'embedding. Cela réduit la surface d'attaque.
Si une injection se produit malgré tout, les données sensibles ne sont plus présentes.
Troisièmement, limitez les permissions des chaînes. Les chaînes LangChain ne doivent lire que les variables d'environnement dont elles ont besoin.
Utilisez un compte de service à portée minimale.
La logique est simple
Le score CVSS est de 9.3. Le correctif est un appel API par document.
La combinaison de CVE-2025-68664 et du risque général lié aux données RAG représente une vraie responsabilité.
La solution est claire : anonymiser à l'ingestion, pas au moment de la requête.
Consultez l'aperçu sécurité et conformité pour les exigences RAG en entreprise.
Sources
- NVD CVE-2025-68664, CVSS 9.3, vulnérabilité de sérialisation LangChain
- Avis de sécurité LangChain, langchain-ai/langchain GitHub, 2025
- OWASP LLM Top 10 : LLM01 Injection de prompt, LLM06 Divulgation d'informations sensibles
- Documentation des types d'entités anonym.legal — 285+ types pris en charge