Pentester un chatbot RAG (Retrieval-Augmented Generation) exige de décomposer le pipeline en cinq maillons distincts — ingestion, embedding, vector store, retrieval, context injection — chacun avec ses propres vulnérabilités et ses propres tests. La majorité des incidents RAG documentés en 2024-2025 viennent d'une mauvaise configuration côté client, pas d'une faille du modèle. Cet article structure la méthodologie de pentest par maillon, avec les tests à exécuter, les outils, et le mapping OWASP LLM Top 10 v2 2025 (LLM08 dominant + LLM01 indirect).
1. Pourquoi le pipeline RAG est une surface d'attaque distincte
Trois raisons font du pipeline RAG une cible d'audit prioritaire.
Surface dominante en pratique
Les incidents publics RAG 2024-2025 montrent une distribution claire : moins de 15% des compromissions viennent d'une faille du modèle LLM lui-même (que le client ne contrôle pas), plus de 75% viennent de configurations défaillantes du pipeline. Auditer le LLM sans auditer le pipeline RAG laisse 75% de la surface d'attaque non couverte.
Surface entièrement sous contrôle du client
Contrairement au modèle (opaque, propriété fournisseur), le pipeline RAG est sous contrôle complet du client : choix du vector store (Pinecone, Qdrant, Weaviate, Milvus, pgvector, Chroma), configuration IAM, sources d'ingestion, modèle d'embedding, logique de retrieval, format du context injecté dans le prompt. Le client porte donc la responsabilité technique et juridique des vulnérabilités du pipeline.
Risques émergents non couverts par les pentests web classiques
Embedding inversion (récupérer le texte depuis le vecteur), retrieval poisoning (manipuler les résultats), cross-tenant leakage (fuite entre tenants partageant un namespace), semantic hijacking (un document optimisé pour matcher tous les queries cibles) — ces classes de risques n'existent pas en pentest web classique et exigent une méthodologie dédiée.
Pour la définition conceptuelle des risques RAG, voir RAG security — définition et Embedding security — définition.
2. Décomposition du pipeline RAG en 5 maillons
Chaque maillon a une fonction précise, des inputs/outputs définis, et des vulnérabilités spécifiques.
| Maillon | Fonction | Vulnérabilités principales | Sévérité typique |
|---|---|---|---|
| 1. Ingestion | Récupérer documents (Drive, SharePoint, S3, scrapers) et préprocesser | Sources non authentifiées, ingestion de prompt injection indirect | High |
| 2. Embedding | Convertir documents en vecteurs (text-embedding-3-large, voyage-3, bge-large) | Embedding inversion, choix de modèle non sécurisé | High |
| 3. Vector store | Stocker vecteurs + metadata, fournir recherche ANN | Cross-tenant leakage, IAM trop large, exposition publique | Critique |
| 4. Retrieval | Trouver les k documents les plus similaires au query | Semantic hijacking, retrieval poisoning, k trop élevé | High |
| 5. Context injection | Injecter les documents retrieved dans le prompt LLM | Indirect prompt injection (LLM01), context size DoS | Critique |
Mapping OWASP LLM Top 10 v2 2025 :
- Maillons 1-4 → LLM08 Vector and Embedding Weaknesses (vulnérabilité dédiée)
- Maillon 5 → LLM01 Prompt Injection (le contenu retrieved est un input non-fiable injecté dans le prompt)
- Transverse → LLM02 Sensitive Information Disclosure si fuite de PII
3. Tester l'ingestion et l'embedding (maillons 1-2)
Tests sur l'ingestion
L'ingestion est la porte d'entrée des documents dans le pipeline. Quatre tests prioritaires :
- Authentification des sources — vérifier qu'un attaquant ne peut pas faire ingérer un document via un canal non authentifié (formulaire public, email, ticket, drive partagé en édition). Tester chaque canal d'ingestion identifié en phase de cartographie.
- Détection de prompt injection à l'ingestion — soumettre des documents contenant des instructions cachées (texte blanc sur blanc, commentaires HTML, métadonnées EXIF, encodage Unicode invisible). Vérifier qu'un classifier de prompt injection est appliqué avant indexation.
- Sanitization des contenus — vérifier que les balises HTML, scripts inline, et formats binaires malveillants sont nettoyés avant embedding.
- Quotas et rate-limit ingestion — un attaquant peut-il saturer le pipeline avec des milliers de documents factices ?
Tests sur l'embedding
- Inventaire du modèle — quel modèle d'embedding est utilisé ? (text-embedding-3-large d'OpenAI, voyage-3 de Voyage AI, bge-large-en de BAAI, all-MiniLM-L6 de sentence-transformers). Vérifier sa version, sa dimensionnalité, et sa licence.
- Embedding inversion — extraire un échantillon d'embeddings du vector store (si accessible en lecture) et tenter de reconstruire le texte source via les techniques documentées (Song et al. 2023, Morris et al. 2024). Le taux de reconstruction quantifie le risque.
- Cohérence du chunking — vérifier que les chunks (typiquement 256-1024 tokens) ne fragmentent pas mal le sens, ce qui dégrade la qualité du retrieval et peut être exploité pour faire matcher des chunks orphelins de leur contexte.
4. Tester le vector store et le retrieval (maillons 3-4)
C'est le cœur du pentest RAG, et la classe de findings la plus impactante.
Audit du vector store
Quatre dimensions à valider sur tout vector store managé (Pinecone, Qdrant Cloud, Weaviate Cloud) ou self-hosted (Milvus, pgvector) :
# Audit IAM Pinecone — exemple Python
# Hypothèse : auditeur dispose d'une clé API d'audit avec droits limités
from pinecone import Pinecone
pc = Pinecone(api_key="<audit_key>")
# 1. Lister les indexes accessibles à la clé d'audit
indexes = pc.list_indexes()
print(f"Indexes accessibles : {len(indexes)}")
# 2. Pour chaque index, vérifier les permissions et namespaces
for index_meta in indexes:
index = pc.Index(index_meta["name"])
stats = index.describe_index_stats()
namespaces = stats.get("namespaces", {})
print(f"\nIndex : {index_meta['name']}")
print(f" Namespaces visibles : {list(namespaces.keys())}")
print(f" Total vectors : {stats.get('total_vector_count')}")
# 3. Test de lecture cross-namespace (devrait échouer si isolation correcte)
try:
vector = index.fetch(ids=["test-vector"], namespace="other-tenant")
print(f" ALERTE : lecture cross-namespace possible — finding Critique")
except Exception as e:
print(f" OK : isolation cross-namespace effective ({type(e).__name__})")
# 4. Test de query sans filter (signaux d'absence de scoping serveur)
sample = index.query(
vector=[0.0] * stats.get("dimension", 1536),
top_k=10,
include_metadata=True,
)
if sample.get("matches"):
print(f" WARN : query sans filter retourne des résultats — vérifier scoping côté backend")Tests cross-tenant
C'est le test le plus important du pentest RAG. Méthodologie standard :
- Créer deux comptes utilisateurs d'audit (tenant A, tenant B) sur l'application cliente.
- Ingérer un document distinct dans chaque tenant via les canaux légitimes (avec marqueur d'audit unique par tenant).
- Depuis le compte tenant A, formuler une requête qui devrait retourner uniquement des résultats tenant A.
- Vérifier que le marqueur tenant B n'apparaît pas dans la réponse.
- Tenter une injection de prompt qui demande explicitement à pivoter vers les documents de l'autre tenant.
Tout résultat positif (présence du marqueur d'un tenant dans une réponse à un autre tenant) est un finding Critique — fuite cross-tenant documentée.
Tests retrieval poisoning et semantic hijacking
- Retrieval poisoning — ingérer un document d'audit qui contient à la fois du contenu sémantiquement très proche du domaine cible ET une charge utile (prompt injection). Tester si ce document est retrieved en réponse à des queries légitimes.
- Semantic hijacking — créer un document optimisé pour matcher de nombreuses queries différentes (par exemple en y répétant les keywords cibles ou en utilisant des techniques d'adversarial embedding). Vérifier l'impact sur le top-k.
5. Tester le context injection (maillon 5)
Le maillon 5 est la passerelle entre le pipeline RAG et le LLM. Tout document retrieved est concaténé dans le prompt envoyé au modèle — c'est par définition une indirect prompt injection (LLM01) si le contenu est malveillant.
Tests prioritaires
- Injection indirecte simple — placer un document piégé dans le tenant d'audit, formuler une requête qui le ramène, vérifier l'effet sur le LLM.
- Délimitation du contexte — vérifier que le prompt template délimite proprement le content retrieved (par exemple via balises ou structures JSON). Sans délimitation explicite, le modèle confond facilement les instructions et le contenu.
- Résistance aux instructions cachées — tester des documents avec instructions en texte blanc sur blanc, commentaires HTML, encodages base64, ROT13.
- DoS contextuel — soumettre des queries qui ramènent un very large context (k=50, documents très longs) et mesurer le coût tokens et la latence. Boucle vers LLM10 Unbounded Consumption.
Patterns de remédiation à valider
| Pattern | Description | Validation au pentest |
|---|---|---|
| Source authentication | Documents ingérés depuis sources signées/authentifiées uniquement | Vérifier qu'un canal non-authentifié rejette l'ingestion |
| Content filtering pré-ingestion | Classifier prompt injection appliqué avant indexation | Tester avec payload connu, vérifier rejet |
| Délimiteurs prompt template | Balises strictes encadrant le retrieved content | Tester injection via fermeture de balise |
| Re-ranking + score threshold | Re-ranker post-retrieval + seuil de similarité minimal | Tester documents borderline (score ~ threshold) |
| Output filtering | DLP en sortie pour bloquer fuite de PII et data sensible | Tester payloads exfiltration via output |
6. Synthèse et plan de remédiation par maillon
| Maillon | Findings types | Remédiation primaire | Délai cible |
|---|---|---|---|
| 1. Ingestion | Source non auth + injection indirecte | Auth source + classifier prompt injection (Lakera, Rebuff) | 7-14 jours |
| 2. Embedding | Modèle obsolète + risque inversion | Modèle récent + accès lecture vector DB strictement contrôlé | 14 jours |
| 3. Vector store | IAM trop large + cross-tenant leakage | Isolation namespace stricte + filter scoping serveur | 14-30 jours |
| 4. Retrieval | Semantic hijacking + retrieval poisoning | Re-ranker + seuil similarité + détection anomalies retrieval | 21-30 jours |
| 5. Context injection | Indirect prompt injection + DoS contextuel | Délimiteurs stricts + classifier en sortie + cap context size | 7-14 jours |
Points clés à retenir
- Le pipeline RAG est la surface d'attaque dominante des chatbots IA en 2024-2025 — plus de 75% des incidents publics viennent de configurations défaillantes du pipeline, pas du modèle.
- Cinq maillons distincts à auditer — ingestion, embedding, vector store, retrieval, context injection. Chacun avec ses propres vulnérabilités et ses propres tests.
- Les tests cross-tenant sont les plus impactants — toute fuite documentée entre tenants est Critique. Méthode standard à deux comptes d'audit.
- L'embedding inversion est une menace réelle — Morris et al. 2024 atteignent environ 87% de reconstruction sur certains embeddings OpenAI. Un vector store accessible en lecture équivaut à une fuite partielle des documents source.
- 70-80% des findings RAG sont des défauts de configuration, pas de produit — la remédiation la plus rentable est de fixer la configuration IAM existante, pas de migrer de vector store.
Pour aller plus loin, voir Comment sécuriser une application RAG pour la dimension défensive complémentaire, Embedding security — définition pour le focus sur LLM08, et Pentest d'un chatbot IA d'entreprise pour la méthodologie globale dans laquelle s'intègre le pipeline RAG. Le bootcamp LLM Security inclut un module dédié au pentest RAG avec lab vector store complet.







