En-tête négligent

Dify IDOR et la chaîne d'approvisionnement RAG : Une plongée technique profonde dans les vulnérabilités de liaison des sources de données

Résumé : Le compromis silencieux des bases de connaissances

Dans le cadre de l'évolution rapide de la pile d'applications "AI-Native" (2025-2026), l'attention des ingénieurs en sécurité a été largement captivée par de nouveaux vecteurs d'attaque : Prompt Injection, Jailbreaking, et Model Inversion. Cependant, alors que des plateformes comme Dify deviennent des orchestrateurs RAG (Retrieval-Augmented Generation) de niveau entreprise, nous assistons à une résurgence des vulnérabilités web classiques, en particulier les suivantes IDOR (Insecure Direct Object Reference)-se manifestant dans la nouvelle "chaîne d'approvisionnement de la connaissance".

Cet article propose une analyse technique exhaustive de la Vulnérabilité IDOR de Dify affectant les liens avec les sources de données distantes (référencé dans le numéro #31839 de GitHub). Nous disséquerons la faille architecturale qui permet à des utilisateurs non privilégiés de manipuler le "cerveau" d'un agent d'intelligence artificielle, nous analyserons le schéma plus large des défaillances du contrôle d'accès dans l'écosystème (référencé dans le document CVE-2025-63387 et CVE-2025-58747), et démontrent comment la prochaine génération de tests de pénétration automatisés doit évoluer pour combler ces lacunes logiques.

L'architecture de la vulnérabilité : comment Dify gère les connaissances

Pour comprendre l'exploit, il faut d'abord comprendre la cible. Dify fonctionne sur une architecture multi-locataires où une instance unique (ou un cluster) sert plusieurs "espaces de travail" (locataires). Au sein de ces locataires, la proposition de valeur principale est la capacité de lier des données non structurées - pages Motion, documents Google Drive, Web Scrapes - à un LLM par le biais d'une base de données vectorielle.

Les DataSourceOauthBinding est l'entité de liaison critique. Elle stocke :

  1. Le prestataire : (par exemple, Notion, GitHub).
  2. Le jeton OAuth : (accès crypté aux données externes).
  3. Le champ d'application : (Quelles sont les pages/répos accessibles).
  4. L'ID de la liaison : Un identifiant unique (souvent un UUID ou un nombre entier) dans la base de données Postgres.

Dans le cadre d'une conception sécurisée, chaque requête vers cette table doit être délimitée par identifiant du locataire. La vulnérabilité IDOR de Dify survient lorsque ce cadrage n'est pas pris en compte dans le point de terminaison de l'API qui gère les mises à jour (PATCH/PUT) ou les suppressions (DELETE).

Autopsie technique : La source de données liant IDOR

La vulnérabilité réside dans les points de terminaison de l'API responsables de l'activation, de la désactivation ou de l'actualisation de ces liaisons de sources de données.

La logique erronée (Reconstruction)

Reconstruisons le chemin du code vulnérable typique de cet IDOR spécifique, en nous basant sur les conclusions du document suivant Dify GitHub Issue #31839. Le cadre du backend (Python/Flask/SQLAlchemy) expose un point de terminaison pour mettre à jour le statut d'une liaison.

Python

`# VULNERABLE ENDPOINT LOGIC (Reconstruction) @api.route('/console/api/data-source/bindings/', methods=['PATCH']) @login_required def update_data_source_binding(binding_id) : """ Met à jour l'état activé/désactivé d'une source de données. """ # 1. Validation d'entrée (syntaxique) - PASS parser = reqparse.RequestParser() parser.add_argument('enabled', type=bool, required=True) args = parser.parse_args()

# 2. Interrogation de la base de données (la faille de sécurité)
# Le développeur interroge uniquement par ID, en supposant que l'UUID est suffisamment entropique
# ou en s'appuyant sur une confiance implicite.
binding = db.session.query(DataSourceOauthBinding).filter(
    DataSourceOauthBinding.id == binding_id
).first()

if not binding :
    raise NotFound("Liaison non trouvée")

# 3. Exécution logique
# CRITICAL FAILURE : Pas de vérification pour voir si binding.tenant_id == current_user.tenant_id
binding.enabled = args['enabled']
binding.updated_at = datetime.utcnow()

db.session.commit()

return jsonify({"result" : "success"}), 200`

La chaîne d'exploitation

Pour un Red Teamer ou un initié malveillant, les étapes de l'exploitation sont méthodiques :

Phase 1 : Reconnaissance et recensement des identités

L'attaquant se connecte à son propre compte Dify et inspecte le trafic réseau lors du basculement d'une intégration de Notion.

  • Demande : PATCH /console/api/data-source/bindings/550e8400-e29b-41d4-a716-446655440000
  • Observation : Le format de l'identifiant. S'il s'agit d'un UUID, l'attaque nécessite une fuite d'ID (Side-Channel ou Information Disclosure). S'il s'agit d'un nombre entier séquentiel (courant dans les anciennes migrations), il est trivialement énumérable.

Note : Même avec les UUID, l'IDOR est possible si d'autres points d'extrémité (comme les GET /console/api/public/stats ou les messages d'erreur) fuient les références d'objets.

Phase 2 : Manipulation entre locataires

L'auteur de l'attaque envoie une requête cURL élaborée à l'aide de son fichier propre JWT (Authorization Bearer token) valide, mais en ciblant un de la victime numéro d'identification de la liaison (binding_id).

Le cambriolage

curl -X PATCH "" \N -H "Authorization : Bearer " \N -H "Content-Type : application/json" \N -d '{"enabled" : false}'

Phase 3 : L'impact - Déni de service RAG (DoS)

Le serveur traite la demande. Étant donné que la requête de la base de données a trouvé l'ID et que le code n'a pas vérifié le propriétaire du locataire, la liaison est désactivée.

  • Résultat : L'agent d'intelligence artificielle de la victime, dont la base de connaissances repose sur cette page de notions, se met soudain à halluciner ou à répondre "Je ne sais pas", car son pipeline d'extraction de contexte a été coupé à distance.
Dify IDOR et la chaîne d'approvisionnement RAG : Une plongée technique profonde dans les vulnérabilités de liaison des sources de données

Le paysage CVE au sens large : Un modèle de contrôle d'accès défaillant

Cet IDOR n'est pas un incident isolé. Il s'inscrit dans un schéma plus large de "contrôle d'accès brisé" (OWASP LLM01) qui affecte l'écosystème Dify à la fin de l'année 2025. L'analyse des CVE récents révèle un problème systémique où la vitesse de livraison des fonctionnalités (agents, flux de travail, MCP) a dépassé la mise en œuvre d'un RBAC (contrôle d'accès basé sur les rôles) rigide.

CVE ID / ProblèmeComposantLogique de vulnérabilitéSévérité
Numéro GitHub #31839Liaison avec la source de donnéesIDOR. Disparu identifiant du locataire dans les requêtes ORM permettant la manipulation à distance des sources RAG.Haut
CVE-2025-63387Caractéristiques du systèmePermissions non sécurisées. Les /console/api/system-features a permis à des utilisateurs non authentifiés de lire les configurations du système. Cela implique un état d'esprit "Default Allow" dans le routage.Moyenne/élevée
CVE-2025-58747MCP OAuthXSS ET RCE. L'implémentation du protocole MCP (Model Context Protocol) fait confiance aux URL des serveurs distants de manière aveugle (fenêtre.ouverte), ce qui permet un XSS.Critique
CVE-2024-11821Modèle ConfigContrôle d'accès. Des utilisateurs non privilégiés pouvaient modifier les configurations du modèle de chatbot via /console/api/apps/{chatbot-id}/model-config.Haut

Analyse :

La récurrence de CVE-2025-63387 et de CVE-2024-11821 met en évidence un problème de sécurité. Autorisation au niveau de l'objet. La plateforme valide la question "L'utilisateur est-il connecté ?" (Authentification) mais ne valide pas rigoureusement la question "Cet utilisateur est-il le même ? (Authentification) mais ne valide pas rigoureusement "Cet utilisateur est-il le propriétaire de cette ligne spécifique dans la base de données ?" (Autorisation).

Les raisons de l'échec de la DAST traditionnelle : Le fossé logique

Les ingénieurs en sécurité posent souvent la question : "Pourquoi Nessus, Burp Suite Pro ou Zap n'ont-ils pas détecté ce problème ?

La réponse réside dans la nature des bugs logiques.

  1. Les codes d'état HTTP sont trompeurs : Pour un scanner, un 200 OK à partir d'une requête PATCH semble être un succès. Le scanner ne sait pas que l'utilisateur A ne devrait pas aurait pu modifier l'objet de l'utilisateur B.
  2. Cécité du contexte : Les scanners ne comprennent pas le concept de "locataires" ou de "liaisons". Ils voient des chaînes opaques.
  3. Dépendance à l'égard de l'État : Le test d'IDOR nécessite une configuration complexe : Créer un utilisateur A, créer un utilisateur B, créer une ressource A, se connecter en tant que B, essayer d'accéder à la ressource A. Les analyses standard sont généralement des sessions mono-utilisateur.

La solution : Pentesting automatisé AI-Native

C'est là que le paradigme passe du "balayage" au "raisonnement". Pour attraper un Dify IDORvous avez besoin d'un moteur qui comprenne les sémantique de l'API.

C'est la philosophie de base de l'ingénierie qui sous-tend Penligent.ai.

Comment Penligent détecte les failles logiques

Contrairement aux scanners basés sur des expressions rationnelles, Penligent utilise de grands modèles de langage (LLM) configurés comme des agents de sécurité autonomes.

  1. Cartographie sémantique de l'API : Penligent lit la spécification Swagger/OpenAPI de Dify et comprend que /bindings/{id} implique une modification des ressources. Il en déduit que {id} est une référence sensible.
  2. Orchestration multi-acteurs : La plateforme met en place deux conteneurs distincts pour les personas :
    • Agent attaquant (utilisateur A)
    • Agent de la victime (utilisateur B)
  3. Fuzzing en fonction du contexte : L'agent attaquant tente explicitement d'accéder aux ressources de la victime.
    • Raisonnement des agents : "Je vois un numéro d'identification de la liaison (binding_id) dans le trafic de l'utilisateur B. Je vais tenter de corriger cet identifiant en utilisant le jeton de session de l'utilisateur A."
    • Analyse du verdict : Si l'API renvoie 200 OK et que l'état de la base de données change, Penligent signale un Confirmé IDOR.

Intégration dans DevSecOps :

YAML

`# .gitlab-ci.yml exemple d'étapes :

  • test de sécurité

penligent-check : stage : security-test script : - penligent-cli scan -target https://staging.dify-instance.com -mode logic-deep-dive seulement : - master`

En intégrant des outils comme Penligent, les équipes de sécurité passent de l'analyse de la conformité à la simulation de l'adversité, en détectant efficacement les failles logiques que représentent CVE-2025-63387 et l'IDOR de la source de données.

Dify IDOR et la chaîne d'approvisionnement RAG : Une plongée technique profonde dans les vulnérabilités de liaison des sources de données

Remédiation : Mise en œuvre de la sécurité au niveau des lignes

Pour les développeurs et les ingénieurs en sécurité qui corrigent Dify (ou d'autres plateformes d'IA similaires), la solution consiste à appliquer des contrôles stricts de propriété au niveau de la couche d'accès aux données (DAL).

Le modèle sécurisé (Python/SQLAlchemy) :

Python

`# SECURE IMPLEMENTATION @api.route('/console/api/data-source/bindings/', methods=['PATCH']) @login_required def update_data_source_binding_secure(binding_id) : # 1. Extraction de contexte # Toujours dériver le tenant_id du jeton de session de confiance, JAMAIS de l'entrée du client current_tenant_id = current_user.current_tenant_id

# 2. Requête ciblée (la solution)
# Nous ne faisons JAMAIS de requête par ID seul. Nous faisons toujours un ET avec l'identifiant du locataire.
binding = db.session.query(DataSourceOauthBinding).filter(
    DataSourceOauthBinding.id == binding_id,
    DataSourceOauthBinding.tenant_id == current_tenant_id
).first()

# 3. Mode d'échec sécurisé
s'il ne s'agit pas d'un binding :
    # Renvoyer 404 Not Found pour empêcher l'énumération des identifiants.
    # Ne renvoyez PAS 403 Forbidden, car cela divulguerait l'existence de l'identifiant aux attaquants.
    annuler(404)

# 4. exécution de la logique
binding.enabled = request.json['enabled']
db.session.commit()
return jsonify({"status" : "updated"})`

Principaux enseignements à tirer de la correction :

  1. Le contexte du locataire est roi : Chaque requête doit comprendre identifiant du locataire.
  2. Faire taire les erreurs : Utilisation 404 Non trouvé pour l'accès non autorisé aux ressources, et non 403. Cela empêche les attaquants de trouver les identifiants de votre base de données (attaque Oracle).
  3. Les UUID ne sont pas des éléments de sécurité : L'utilisation d'UUID permet d'éviter l'énumération séquentielle, mais n'empêche pas l'IDOR en cas de fuite de l'ID. Le contrôle d'accès est la seule véritable défense.

L'avenir de l'IA AppSec

Les Dify IDOR constitue une étude de cas cruciale pour l'industrie. Alors que nous nous empressons de construire des avenirs "agentiques" où l'IA effectue des actions en notre nom, les fondements de la sécurité web sous-jacente ne peuvent être ignorés. Un Data Source Binding compromis n'est pas seulement synonyme de perte de données ; à l'ère du RAG, il est synonyme de distorsion de la réalité pour le modèle d'IA.

Les ingénieurs en sécurité doivent s'adapter. Nous devons aller au-delà des simples attaques par injection et nous concentrer sur les relations logiques complexes entre les locataires, les agents et les bases de connaissances. Que ce soit par un examen rigoureux du code ou par l'adoption de plateformes de test natives de l'IA comme Penligent, la sécurisation de la "couche de connaissances" est le défi déterminant de 2026.

Références et lectures complémentaires :

Partager l'article :
Articles connexes
fr_FRFrench