flawopen.com/AI Security/langroid-neo4j-cypher-injection-cve-2026-55615
Langroid CVE-2026-55615 : injection prompt-to-Cypher
Langroid transmettait à Neo4j le Cypher du modèle sans le valider. Passez à 0.65.5 ; les droits de la base restent la frontière de sécurité.[1], [2], [4]
Une bibliothécaire reçoit une question en langage courant et remet directement les instructions de base de données obtenues à un employé puissant. Si une note hostile modifie la question, l’employé exécute tout de même ces instructions. CVE-2026-55615 permettait à un contenu non fiable d’influencer le Cypher envoyé par Langroid à Neo4j.[1]
Concepts Clés et Termes
Cypher- Langage de requête de Neo4j pour lire et modifier les données du graphe. Les procédures supplémentaires dépendent de la configuration et des droits du compte.[1]
Neo4jChatAgent- Agent Langroid qui transforme une demande en langage naturel en Cypher et l’envoie à Neo4j via des outils de lecture ou de création.[1], [3]
Prompt injection- Une entrée non fiable modifie le comportement du modèle. Les requêtes produites par le modèle doivent être traitées comme des entrées non fiables.[1]
Least-privilege database role- Identité de base de données limitée aux données et opérations nécessaires. Cette frontière reste essentielle même si l’application valide les requêtes.[1], [5]
Validateur de requêtes Cypher- Le validateur de Langroid 0.65.5 applique des contrôles de mots-clés et de motifs. La documentation avertit qu’ils peuvent être contournés : ils relèvent de la défense en profondeur, pas de la frontière d’autorisation. Les rôles Neo4j doivent imposer les droits d’accès.[6], [3]
Correspondances de référentiels
- Référence CWE pour la faiblesse décrite dans ce guide : CWE-74
Déroulement de l'Attaque Étape par Étape
Un agent graphe vulnérable accepte des requêtes du modèle
Les versions de Langroid jusqu’à 0.65.4 sont concernées. L’attaque suppose qu’un adversaire influence le prompt directement ou via du contenu récupéré, puis que le modèle utilise un outil Neo4jChatAgent. L’avis attribue CWE-74 et CVSS 4.0 9,2 (critique).[1], [2]
Le contenu influence le Cypher transmis par l’agent
Dans le chemin vulnérable, cypher_retrieval_tool transmettait msg.cypher_query à read_query et cypher_creation_tool envoyait la requête à write_query. L’avis suit ces valeurs jusqu’à session.run(query, parameters) et tx.run(query, parameters), sans validation intermédiaire.[1], [3]
Les droits de la base déterminent l’impact immédiat
L’outil de lecture peut révéler les données accessibles au compte connecté ; l’outil de création peut modifier ou supprimer les données permises par ce compte. L’avis mentionne aussi la récupération distante via LOAD CSV. L’accès aux fichiers ou commandes de l’hôte dépend de procédures activées et de droits accordés.[1]
La version 0.65.5 ajoute des contrôles dans les outils
La résolution du mainteneur indique que 0.65.5 ajoute allow_dangerous_operations désactivé par défaut, limite la lecture aux requêtes en lecture seule et vérifie certaines primitives dans les outils. Ce sont des défenses en profondeur, pas une autorisation. La résolution du mainteneur et le guide SQL de Langroid désignent les rôles de base de données à privilèges minimaux comme frontière de sécurité.[1], [3], [4], [5]
Code Source : Vulnérable vs Sécurisé
L’extrait vulnérable suit le chemin de l’avis ; l’exemple corrigé représente le comportement de 0.65.5 sans reproduire le patch mot à mot. Le correctif valide à la frontière de l’outil, limite la lecture et contrôle les opérations dangereuses. Traitez les contrôles de requête comme une défense en profondeur, pas comme une autorisation. La résolution du mainteneur et le guide SQL de Langroid désignent les rôles Neo4j à privilèges minimaux comme frontière de sécurité ; isolez aussi le processus agent. Langroid précise que ces contrôles de mots-clés et de motifs peuvent être contournés ; conservez les droits Neo4j comme frontière de contrôle.[1], [3], [4], [6]
# Chemin vulnérable de Neo4jChatAgent (Langroid <= 0.65.4).
def cypher_retrieval_tool(self, msg: CypherRetrievalTool):
query = msg.cypher_query
return self.read_query(query)
def read_query(self, query: str):
with self.driver.session() as session:
return session.run(query, parameters=None)
# Comportement de la version 0.65.5 : valider à la frontière de l’outil exposée au LLM.
def cypher_retrieval_tool(self, msg: CypherRetrievalTool):
query = msg.cypher_query
rejection = validate_cypher_query(
query, is_write=False,
allow_dangerous=self.config.allow_dangerous_operations,
)
if rejection is not None:
return rejection
return self.read_query(query)
Liste de Contrôle de Sécurité pour l'Ingénierie
- ✓Recensez Langroid et ses fichiers de verrouillage ; mettez à jour les environnements concernés vers 0.65.5 ou ultérieur et reconstruisez les images.[1], [4]
- ✓Laissez
allow_dangerous_operations=Falsesauf exception documentée et approuvée.[1], [4] - ✓Utilisez un compte Neo4j dédié par agent et accordez uniquement les données, étiquettes, opérations et procédures nécessaires.[1], [5]
- ✓Désactivez APOC, dbms.security, LOAD CSV et les capacités inutiles de fichiers, réseau ou système ; vérifiez les droits effectifs.[1]
- ✓Gardez les outils de lecture en lecture seule et autorisez séparément les écritures importantes.[1], [4]
- ✓Testez une lecture normale et vérifiez qu’une requête inoffensive de test de politique est refusée avant l’appel au driver.[3], [4]
- ✓Limitez l’accès de l’hôte agent aux fichiers, secrets et réseau.[1]
- ✓Examinez les journaux Neo4j et traces agent pendant la période vulnérable ; renouvelez les secrets potentiellement exposés.