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 :
- Le prestataire : (par exemple, Notion, GitHub).
- Le jeton OAuth : (accès crypté aux données externes).
- Le champ d'application : (Quelles sont les pages/répos accessibles).
- 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.

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ème | Composant | Logique de vulnérabilité | Sévérité |
|---|---|---|---|
| Numéro GitHub #31839 | Liaison avec la source de données | IDOR. Disparu identifiant du locataire dans les requêtes ORM permettant la manipulation à distance des sources RAG. | Haut |
| CVE-2025-63387 | Caractéristiques du système | Permissions 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-58747 | MCP OAuth | XSS 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-11821 | Modèle Config | Contrô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.
- 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. - Cécité du contexte : Les scanners ne comprennent pas le concept de "locataires" ou de "liaisons". Ils voient des chaînes opaques.
- 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.
- 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. - Orchestration multi-acteurs : La plateforme met en place deux conteneurs distincts pour les personas :
- Agent attaquant (utilisateur A)
- Agent de la victime (utilisateur B)
- 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 OKet que l'état de la base de données change, Penligent signale un Confirmé IDOR.
- Raisonnement des agents : "Je vois un
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.

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 :
- Le contexte du locataire est roi : Chaque requête doit comprendre
identifiant du locataire. - Faire taire les erreurs : Utilisation
404 Non trouvépour l'accès non autorisé aux ressources, et non403. Cela empêche les attaquants de trouver les identifiants de votre base de données (attaque Oracle). - 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 :
- GitHub Issue #31839 : Vulnérabilité IDOR de Dify DataSourceOauthBinding
- Avis GitHub : Permissions des fonctionnalités du système Dify (CVE-2025-63387)
- Détail NVD : CVE-2025-58747 (MCP OAuth XSS)
- OWASP Top 10 pour les applications LLM : IDOR et empoisonnement de données
- Blog de Penligent : Pourquoi les DAST traditionnels ne détectent pas les vulnérabilités logiques

