LLM Security

Pentest de chatbot RAG : tester le pipeline de récupération

Audit offensif d'un pipeline RAG : ingestion, embedding, vector store, retrieval, context injection. Méthodologie par maillon et outils 2025.

Naim Aouaichia
10 min de lecture
  • Pentest RAG
  • Pipeline RAG
  • Vector store
  • Embedding security
  • LLM08
  • Retrieval poisoning
  • Indirect prompt injection
  • Audit IA

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.

MaillonFonctionVulnérabilités principalesSévérité typique
1. IngestionRécupérer documents (Drive, SharePoint, S3, scrapers) et préprocesserSources non authentifiées, ingestion de prompt injection indirectHigh
2. EmbeddingConvertir documents en vecteurs (text-embedding-3-large, voyage-3, bge-large)Embedding inversion, choix de modèle non sécuriséHigh
3. Vector storeStocker vecteurs + metadata, fournir recherche ANNCross-tenant leakage, IAM trop large, exposition publiqueCritique
4. RetrievalTrouver les k documents les plus similaires au querySemantic hijacking, retrieval poisoning, k trop élevéHigh
5. Context injectionInjecter les documents retrieved dans le prompt LLMIndirect prompt injection (LLM01), context size DoSCritique

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 :

  1. Créer deux comptes utilisateurs d'audit (tenant A, tenant B) sur l'application cliente.
  2. Ingérer un document distinct dans chaque tenant via les canaux légitimes (avec marqueur d'audit unique par tenant).
  3. Depuis le compte tenant A, formuler une requête qui devrait retourner uniquement des résultats tenant A.
  4. Vérifier que le marqueur tenant B n'apparaît pas dans la réponse.
  5. 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

PatternDescriptionValidation au pentest
Source authenticationDocuments ingérés depuis sources signées/authentifiées uniquementVérifier qu'un canal non-authentifié rejette l'ingestion
Content filtering pré-ingestionClassifier prompt injection appliqué avant indexationTester avec payload connu, vérifier rejet
Délimiteurs prompt templateBalises strictes encadrant le retrieved contentTester injection via fermeture de balise
Re-ranking + score thresholdRe-ranker post-retrieval + seuil de similarité minimalTester documents borderline (score ~ threshold)
Output filteringDLP en sortie pour bloquer fuite de PII et data sensibleTester payloads exfiltration via output

6. Synthèse et plan de remédiation par maillon

MaillonFindings typesRemédiation primaireDélai cible
1. IngestionSource non auth + injection indirecteAuth source + classifier prompt injection (Lakera, Rebuff)7-14 jours
2. EmbeddingModèle obsolète + risque inversionModèle récent + accès lecture vector DB strictement contrôlé14 jours
3. Vector storeIAM trop large + cross-tenant leakageIsolation namespace stricte + filter scoping serveur14-30 jours
4. RetrievalSemantic hijacking + retrieval poisoningRe-ranker + seuil similarité + détection anomalies retrieval21-30 jours
5. Context injectionIndirect prompt injection + DoS contextuelDélimiteurs stricts + classifier en sortie + cap context size7-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.

Questions fréquentes

  • Pourquoi auditer le pipeline RAG séparément du modèle LLM ?
    Le modèle LLM est généralement opaque (fournisseur SaaS) et ses vulnérabilités intrinsèques relèvent du fournisseur. Le pipeline RAG est entièrement sous contrôle du client : choix du vector store, configuration IAM, sources d'ingestion, logique de retrieval, format du context injecté. C'est aussi la surface d'attaque dominante en pratique : la majorité des incidents publics RAG documentés en 2024-2025 viennent du pipeline mal configuré, pas du modèle.
  • Quel vector store est le plus sûr par défaut ?
    Aucun n'est sécurisé par défaut — la sécurité dépend entièrement de la configuration IAM et de l'isolation tenant côté client. En pratique : Pinecone et Qdrant Cloud (managés) imposent une auth forte avec scopes par index/collection ; Weaviate et Milvus self-hosted exigent une configuration explicite ; pgvector dépend du PostgreSQL sous-jacent (souvent mal configuré). Le ranking par sécurité native ne fait pas sens — l'audit doit valider la configuration concrète, pas le choix de produit.
  • Combien de temps prend un pentest pipeline RAG complet ?
    Pour une application RAG standard (1 source, vector store managé, retrieval k=5, prompt template fixe), comptez 5 à 8 jours-homme. Pour une application multi-sources (SharePoint + Drive + base interne), multi-tenant ou avec re-ranking ML, comptez 12 à 20 jours-homme. La phase de tests cross-tenant et d'embedding inversion est la plus chronophage car elle exige un environnement d'audit isolé avec données factices.
  • Peut-on récupérer le contenu source à partir des embeddings ?
    Partiellement à largement, selon le modèle d'embedding et la dimensionnalité. Le paper Song et al. 2023 'Text Embeddings Reveal (Almost) As Much As Text' a démontré reconstruction d'environ 40% du texte source depuis des embeddings sentence-transformers. Le paper Morris et al. 2024 'Language Model Inversion' atteint environ 87% sur certains embeddings OpenAI avec un attaquant disposant de paires (texte, embedding) pour entraînement. Implication audit : un vector store accessible en lecture par un attaquant équivaut à une fuite partielle des documents source.
  • Comment tester l'isolation cross-tenant d'un RAG ?
    Méthode standard : créer deux comptes utilisateurs d'audit (tenant A et tenant B) sur l'application. Ingérer des documents distincts dans chaque tenant via les canaux légitimes. Depuis le compte tenant A, formuler des prompts qui devraient retourner uniquement des documents tenant A — vérifier qu'aucun document tenant B n'apparaît dans la réponse. Tester aussi l'injection de prompt qui cherche à pivoter vers les documents de l'autre tenant. Tout résultat positif est un finding de sévérité Critique.

Écrit par

Naim Aouaichia

Expert cybersécurité et fondateur de Zeroday Cyber Academy

Expert cybersécurité avec un master spécialisé et un parcours hybride : développement, DevOps, DevSecOps, SOC, GRC. Fondateur de Hash24Security et Zeroday Cyber Academy. Formateur et créateur de contenu technique sur la cybersécurité appliquée, la sécurité des LLM et le DevSecOps.