Cadre R.A.I.L.G.U.A.R.D. : Des vulnérabilités des modèles au raisonnement sécurisé

Notre parcours vers la conception du cadre R.A.I.L.G.U.A.R.D. a commencé il y a un peu plus d’un mois, suite à la lecture d’un article de Pillar Security’s article décrivant comment les agents de codage GenAI peuvent être exploités via des attaques par injection de prompt ou empoisonnement de règles Cursor.
Les assistants de codage basés sur l’IA générative comme Copilot, Cursor ou Windsurf sont désormais largement utilisés dans l’industrie du logiciel. Ce qui nous a le plus frappés, ce n’est pas seulement l’étendue de la surface d’attaque — mais la cause racine. Ces outils sont alimentés par de grands modèles de type Transformer.
Pour comprendre pourquoi ces assistants sont sujets à des failles de sécurité, il faut observer l’architecture ANN + Transformer. Ce qui les rend puissants — leur capacité à absorber le contexte et prédire le prochain token — les rend également vulnérables à :
-
des injections de prompt (notamment indirectes et distantes)
-
des hallucinations
-
des mauvaises interprétations induites par un contexte trompeur
Comprendre l’impact du concept de "self-attention" sur la sécurité
Avant tout, il est essentiel de comprendre la self-attention dans les LLMs pour cerner les problèmes de sécurité associés à la GenAI.
La self-attention permet aux modèles de pondérer les tokens par pertinence et non uniquement selon leur position dans la séquence. Cela leur permet de suivre des dépendances à longue distance, comme l’association entre un bloc try
et son catch
plusieurs lignes plus loin. Le modèle construit ainsi une carte probabiliste de ce qui semble important dans l’entrée.
⇒ L’idée clé : le contexte est dynamique, et la compréhension de “l’intention” par le modèle peut facilement être erronée.
Example: Insecure by Context
Comparaison visuelle entre une sortie non sécurisée et une alternative guidée par RAILGUARD :
# Prototype for a simple admin panel to quickly demonstrate proof of concept
query = f"SELECT * FROM users WHERE email = '{email}'"
Ce code est dangereux -> pas uniquement à cause de l’interpolation de chaîne.
La présence du commentaire (prototype
, rapide
, POC
) pousse le modèle à minimiser les exigences de sécurité. Il a sans doute vu des milliers d’exemples similaires (code de démo, GitHub, Stack Overflow...) où la rapidité primait sur la sécurité.
Au lieu d’imposer l’usage d’ORM ou de requêtes préparées, le modèle privilégie la simplicité, au détriment des vérifications de sécurité.
Reconnaissance de motifs ≠ Raisonnement sécurisé
Le concept de "self-attention" permet au modèle de reproduire des motifs vus précédemment, même s’ils sont inadaptés ou dangereux.
Pire encore, les LLMs peuvent :
-
suivre des commentaires empoisonnés
-
être influencés par des caractères invisibles
-
être trompés par des noms de variables perfides
Les assistants basés sur des Transformers sont vulnérables par conception. Le LLM ne “sait” pas que ce qu’il génère, est dangereux, il suit juste des motifs qui semblent corrects dans le contexte.
Sécurité au moment du raisonnement : pourquoi nous avons créé R.A.I.L.G.U.A.R.D.
C’est pour cela que nous avons conçu le cadre R.A.I.L.G.U.A.R.D. : pour injecter des contraintes de raisonnement sécurisé avant même la génération du code.
RAILGUARD introduit des signaux de sécurité dans le raisonnement du modèle via :
-
des règles métier (ex. : CursorRules),
-
des contraintes renforcées,
-
des contextes sécurisés par défaut.
Les 8 Blocs du cadre R.A.I.L.G.U.A.R.D.
Chaque bloc contribue à façonner la sécurité au moment du raisonnement. Les voici :
R — Risk First (Prioritéau risque)
Définir l’objectif de sécurité de la règle. Inciter le LLM à « réfléchir » avant d’agir.
Concrètement, cela implique que le modèle effectue une vérification interne, une forme de modélisation des menaces : qu’est-ce qui pourrait mal tourner en répondant à cette requête ?
Par exemple, si l’utilisateur demande d’analyser un fichier téléchargé, un LLM orienté "Risk First" pourrait reconnaître le risque de contenu malveillant et inclure des pratiques de traitement de fichier sécurisé (ou au moins émettre un avertissement), plutôt que de générer aveuglément un parseur rapide et fragile.
A — Attached Constraints (Contraintes attachées)
Spécifier ce qui ne doit jamais se produire (limites, lignes rouges) pour éviter les régressions. Le principe des “Attached Constraints” garantit que l’IA n’opère jamais sans règle claire. Dans les systèmes actuels, un assistant IA de codage ne dispose souvent que d’un filtre de contenu générique ou d’un réglage d’alignement de haut niveau.
RAILGUARD, à l’inverse, injecte un ensemble détaillé de contraintes de sécurité et de style de code, transmises au modèle (par exemple via un prompt système ou un fichier de contexte persistant). Ces contraintes couvrent : les pratiques cryptographiques approuvées, les fonctions interdites, les conventions de nommage, etc.
Essentiellement, l’IA transporte avec elle un standard de codage sécurisé obligatoire.
Cela compense la tendance des Transformers à être trop permissifs : le modèle entend en permanence une petite voix lui rappeler :
“Souviens-toi, voici les règles à suivre.”
Avec ces contraintes attachées, un prompt malveillant (comme un jailbreak) ne pourra pas les outrepasser. Pourquoi ? Parce que le modèle donnera toujours priorité aux règles attachées.
I — Interpretative Framing (Encadrement interprétatif)
L’idée est de guider la manière dont le LLM doit interpréter les prompts de façon sécurisée et éviter la confiance aveugle dans des instructions vagues.
L’encadrement interprétatif signifie que l’IA va reformuler ou réinterpréter en interne la requête pour s’assurer qu’elle reste conforme à un comportement sûr et souhaité.
Les LLMs sont très sensibles au contexte : un léger changement de formulation peut modifier radicalement la sortie.Par exemple, un utilisateur demande :
“Ouvre un fichier et affiche la première ligne.”
Un modèle classique le fera littéralement.
Un LLM encadré par RAILGUARD pourrait plutôt interpréter en interne :
“Ouvre un fichier (en t’assurant que le chemin est sûr et en gérant les erreurs), puis affiche la première ligne (en évitant tout contenu dangereux).”
L’idée n’est pas de changer l’intention, mais d’intégrer les considérations de sécurité implicites.
L — Local Defaults (Valeurs par défaut locales)
Définir des valeurs sécurisées par défaut au niveau du projet ou de l’environnement (ex. : utiliser des variables d’environnement plutôt que des secrets en clair). Le principe de “Local Defaults” garantit que, en l’absence d’instructions explicites, le modèle adopte toujours des pratiques sécurisées par défaut. Exemples :
-
Génération d’API → inclure automatiquement l’authentification et la validation des entrées
-
Génération de requêtes SQL → utiliser par défaut des requêtes préparées ou un ORM
RAILGUARD fait de la sécurité par défaut une norme intégrée dans les processus GenAI.
G — Generative Path Checks (Vérification du chemin génératif)
Imposer une séquence de raisonnement à suivre avant que le modèle n’émette du code, avec une boucle de rétroaction pendant la génération.
Le modèle est invité à raisonner sur sa solution avant de produire la sortie.
Cette approche permet de détecter les erreurs qui pourraient autrement devenir des vulnérabilités ou des hallucinations. Elle améliore à la fois la sécurité et la précision.
U — Uncertainty Disclosure (Déclaration d’incertitude)
Dire explicitement au modèle quoi faire en cas de doute : demander, avertir, ou s’abstenir.Les hallucinations sont un problème bien connu des LLMs. Dans le codage assisté par GenAI, l’incertitude peut surgir si le prompt est vague ou hors du champ de connaissance du modèle.
Le vrai danger survient lorsque le LLM affirme avec confiance des choses incorrectes — ce qui peut introduire des failles de sécurité.
A — Auditability (Auditabilité)
Ajouter des commentaires ou marqueurs de trace pour permettre l’audit humain.
L’auditabilité, c’est garantir que les actions de l’IA sont traçables et compréhensibles.
Dans RAILGUARD, cela signifie que l’IA doit justifier ses décisions, en particulier celles liées à la sécurité.
En pratique, cela peut se traduire par des commentaires explicatifs :
“// Using prepared statements to prevent SQL injection” ou “// Added rate limiting to mitigate brute-force attacks as per security policy.”
Ces annotations permettent la vérification et la relecture par des humains — et sont, selon nous, un filet de sécurité incontournable.
R+D — Revision + Dialogue (Révision + Dialogue)
Cette combinaison reconnaît que le code est un processus itératif, et que l’IA doit agir comme partenaire collaboratif, pas comme oracle infaillible.
Aucun code complexe n’est parfait dès le premier jet — ni écrit par un humain, ni par une IA. Avec la révision, l’IA peut dire : “laisse-moi réessayer” ou accepter des retours pour améliorer sa proposition. Avec le dialogue, l’IA reste engagée dans une conversation avec le développeur, au lieu de livrer du code et disparaître.
En matière de sécurité, cela permet une amélioration continue et un véritable défense en profondeur. En pratique, cela signifie que les devs — ou même d’autres LLMs — peuvent interroger ou corriger le code généré via des /commands
.
L’avenir de la sécurité applicative (AppSec) est génératif
Nous comprenons désormais que les modèles basés sur les transformers ne « comprennent » pas le code, ils le contextualisent. Ils ne suivent pas des règles, ils reproduisent des motifs, interpellent, et évaluent la pertinence. C’est leur force, mais aussi leur faiblesse.
La sécurité à l’ère de la GenAI ne peut pas se reposer uniquement sur des linters statiques, des vérificateurs de règles ou des correctifs post-génération. Nous devons agir là où le modèle raisonne, c’est-à-dire au niveau de la self-attention, de la pondération des tokens et du raisonnement contextuel probabiliste.
Le cadre RAILGUARD ne cherche pas à restreindre le modèle, il cherche à l’éduquer.
Il construit un échafaudage comportemental sécurisé avant même la première ligne de code générée.
En appliquant les principes de Risk First, Attached Constraints, Interpretative Framing, Local Defaults, Generative Path Checks, Uncertainty Disclosure, Auditability, and Revision + Dialogue, nous mettons en place une défense en profondeur autour du processus génératif de l’IA. En résumé : RAILGUARD façonne un raisonnement sécurisé. Avec tout cela, Cursor Rules devient le support, et RAILGUARD devient l’état d’esprit. Ensemble, ils permettent de construire des pipelines de génération de code qui ne se contentent pas de produire du code qui semble correct, mais du code qui raisonne de manière sécurisée, par conception.
Le code généré par IA est déjà très répandu, et pourrait bien devenir la principale source de code dans un avenir proche. Sa sécurité doit être pensée et encadrée dès la génération.
Merci de nous avoir lus,
L’équipe BrightOnLABS