Votre agent a un intermédiaire que vous n'avez pas vérifié
Des chercheurs ont acheté 28 routeurs LLM API payants sur Taobao, Xianyu et des boutiques hébergées par Shopify, et en ont collecté 400 autres auprès de communautés publiques. Ils ont instrumenté les requêtes avec des identifiants plantés et sondé chaque routeur pour voir ce qu’il faisait du trafic.1
Dix-sept de ces routeurs ont touché à des identifiants canary AWS plantés dans les requêtes. Un a vidé l’ETH d’une clé privée placée comme appât. Une clé OpenAI divulguée que l’équipe avait mise en place comme pot de miel a généré 100M de tokens GPT-5.4 et, selon le résumé, « plus de sept sessions Codex » avant qu’ils ne la retirent.1 Des leurres distincts faiblement configurés ont produit 2 milliards de tokens facturés, 99 identifiants à travers 440 sessions Codex, et 401 sessions déjà en cours d’exécution en mode YOLO autonome.1
Le routeur LLM API est la nouvelle surface d’attaque. Personne ne l’audite.
TL;DR
Les routeurs LLM API tiers sont des proxys de couche applicative avec un accès en clair complet à chaque charge utile JSON en transit entre votre agent et le modèle en amont. Aucun fournisseur n’applique d’intégrité cryptographique entre le client et l’amont. Un nouveau papier arxiv de Liu, Shou, Wen, Chen et Fang présente la première étude systématique de cette surface d’attaque, et les données de terrain sont laides : 1 des 28 routeurs payants et 8 des 400 routeurs gratuits injectaient activement du code malveillant dans les réponses, 2 déployaient des déclencheurs d’évasion adaptative, 17 ont touché à des identifiants canary AWS plantés, et 1 a vidé l’ETH d’une clé privée plantée.1 Les auteurs formalisent deux classes d’attaque fondamentales plus deux variantes d’évasion adaptative, puis construisent un proxy de recherche appelé Mine qui implémente « les quatre classes d’attaque » (selon leur formulation) contre quatre frameworks d’agents publics et évaluent trois défenses côté client déployables.1 Si votre agent utilise un routeur que vous n’avez pas construit, vous avez une frontière de confiance que vous n’avez jamais auditée.
Points clés à retenir
- Opérateurs d’agents : Chaque routeur LLM API entre votre client et le modèle en amont est un proxy de couche applicative avec un accès en clair à chaque requête et réponse. Aucune intégrité cryptographique n’est appliquée. Si vous utilisez un routeur acheté sur une place de marché ou récupéré depuis une liste communautaire publique, traitez-le comme un intermédiaire hostile jusqu’à preuve du contraire.
- Constructeurs de harnais : Vos hooks PreToolUse s’exécutent avant l’exécution de l’outil, mais un routeur malveillant modifie la réponse du modèle après la génération et avant qu’elle n’atteigne votre hook. Ajoutez une validation côté réponse à votre pile de hooks, et envisagez des portes de politique fail-closed sur les formes de réponse anormales.
- Quiconque exécute le mode YOLO : Quatre cent une sessions dans le pot de miel des chercheurs s’exécutaient déjà en mode YOLO autonome.1 Un routeur modifiant les appels d’outils dans une session autonome a un rayon d’action bien plus large qu’un routeur modifiant une réponse que vous allez lire. N’exécutez pas le mode YOLO à travers un routeur que vous ne contrôlez pas.
Qu’est-ce qu’un routeur, exactement ?
Dans le contexte de ce papier, un routeur LLM API est un service tiers qui se place entre votre client et un ou plusieurs fournisseurs de modèles en amont. Vous envoyez des requêtes au routeur en utilisant une API compatible OpenAI. Le routeur dispatche ces requêtes vers l’amont de son choix — GPT-5, Claude, Gemini, un modèle à poids ouverts, un pool de tous — et vous renvoie la réponse dans la même forme.1
Les routeurs existent parce que l’écosystème LLM est en désordre. Les gens veulent une seule clé API qui fonctionne avec tous les modèles. Les gens veulent de l’arbitrage de prix — acheter des tokens en gros, les revendre moins cher. Les gens veulent des contournements géographiques pour les régions où l’accès direct au fournisseur est restreint. Les gens veulent tester plusieurs modèles avec un seul client. Toutes ces raisons sont légitimes, et un marché des routeurs sain les sert toutes.
Le problème est qu’un routeur est un proxy de couche applicative. Il ne se contente pas de transférer des octets. Il lit la JSON de la requête, choisit un amont, réécrit éventuellement la requête, la transmet, lit la réponse, réécrit éventuellement la réponse, et la renvoie. Chaque étape de ce pipeline se produit en clair sur l’infrastructure du routeur.1
Il n’y a pas d’équivalent TLS ici. TLS protège les octets de votre client vers le routeur et du routeur vers le modèle en amont. Il ne fait rien pour protéger la charge utile contre le routeur. Aucun fournisseur n’applique d’intégrité cryptographique entre le client d’origine et le modèle final — il n’y a pas d’assertion signée que la requête reçue par le modèle est la même que celle envoyée par le client, et pas d’assertion signée que la réponse reçue par le client est la même que celle générée par le modèle.1
Cette absence est la surface d’attaque.
Les données de terrain
Les chercheurs ont acheté 28 routeurs payants sur trois places de marché (Taobao, Xianyu, boutiques hébergées par Shopify) et collecté 400 routeurs gratuits auprès de communautés publiques. Ils ont fait passer chaque routeur à travers une série de sondes avec des requêtes instrumentées contenant des identifiants plantés, des charges utiles connues et des chaînes marqueurs.1
Voici ce qu’ils ont trouvé :
| Constat | Nombre | Notes |
|---|---|---|
| Routeurs payants injectant activement du code malveillant dans les réponses | 1 (sur 28) | Répartition explicite dans le résumé |
| Routeurs gratuits injectant activement du code malveillant dans les réponses | 8 (sur 400) | Répartition explicite dans le résumé |
| Routeurs déployant des déclencheurs d’évasion adaptative | 2 | Répartition payant/gratuit non précisée dans le résumé |
| Routeurs touchant les identifiants canary AWS des chercheurs | 17 | Répartition payant/gratuit non précisée dans le résumé |
| Routeurs vidant l’ETH d’une clé privée des chercheurs | 1 | Répartition payant/gratuit non précisée dans le résumé |
Le constat sur l’évasion adaptative est celui qui devrait vous empêcher de dormir. Un déclencheur d’évasion adaptative signifie que le routeur se comporte normalement la plupart du temps et bascule en comportement d’attaque sous des conditions spécifiques — une forme de requête particulière, une empreinte client particulière, une cadence particulière. Vous ne pouvez pas l’attraper en échantillonnant des requêtes aléatoires, parce que le routeur sait quand il est échantillonné et se comporte bien.
Les identifiants canary sont des fils-pièges : ils se déclenchent lorsque quelqu’un tente de les utiliser. Dix-sept routeurs « touchant » à ceux-ci signifie qu’au moins dix-sept routeurs ont extrait les identifiants des charges utiles en transit et ont tenté de les utiliser contre AWS.1 Le résumé ne détaille pas le mécanisme exact par routeur, mais la conception du fil-piège implique que toucher = utiliser.
Le seul routeur qui a vidé l’ETH d’une clé privée appartenant aux chercheurs est un constat plus fort. Une clé privée dans un prompt n’est pas un fil-piège d’identifiant — c’est un appât qui ne produit des preuves de compromission que lorsque le routeur vide effectivement le portefeuille. Un routeur l’a fait.1
Les deux études d’empoisonnement
Les chercheurs ont mené deux études supplémentaires pour montrer que des routeurs ostensiblement bénins peuvent être entraînés dans la même surface d’attaque par exposition tierce.
Étude 1 : clé OpenAI divulguée. Les chercheurs ont divulgué une clé API OpenAI fonctionnelle comme si elle avait été exposée par une erreur de développeur. Pendant la fenêtre d’observation, cette seule clé divulguée — selon le résumé — a généré 100M de tokens GPT-5.4 et « plus de sept sessions Codex » via des routeurs qui l’ont récupérée.1 Quelqu’un — ou beaucoup — a trouvé la clé, acheminé des requêtes à travers des routeurs communautaires en l’utilisant, et brûlé 100M de tokens de calcul. Le routeur était une couche de blanchiment pour une clé volée.
Étude 2 : leurres faiblement configurés. Les chercheurs ont mis en place des points de terminaison leurres faiblement configurés. Les leurres ont produit 2 milliards de tokens facturés, 99 identifiants à travers 440 sessions Codex, et — voici la ligne critique — 401 sessions déjà en cours d’exécution en mode YOLO autonome.1
Quatre cent une sessions autonomes acheminant déjà à travers un seul ensemble de leurres. Chacune de ces sessions était une surface d’attaque en direct où un intermédiaire malveillant pouvait injecter des appels d’outils, exfiltrer des secrets, ou modifier la sortie du modèle, et l’agent exécuterait tout ce qui revenait sans humain dans la boucle. Le nombre 401 est ce qu’un leurre de recherche a attrapé — la population opérationnelle acheminant à travers des intermédiaires non contrôlés est nécessairement plus grande.
Deux classes d’attaque fondamentales et deux variantes adaptatives
Le papier formalise deux classes d’attaque fondamentales et deux variantes d’évasion adaptative. Le résumé est explicite sur la taxonomie : AC-1 et AC-2 sont les classes fondamentales ; AC-1.a et AC-1.b sont des variantes d’AC-1. Le proxy de recherche Mine implémente « les quatre classes d’attaque » (selon la formulation du résumé) contre quatre frameworks d’agents publics.1
AC-1 : injection de charge utile (classe fondamentale). Le routeur modifie la réponse pour injecter des instructions supplémentaires, des appels d’outils ou du contenu sur lesquels l’agent client agit. L’agent pense lire une sortie du modèle ; il lit une sortie de celui qui possède le routeur.
AC-2 : exfiltration de secrets (classe fondamentale). Le routeur lit les secrets dans les requêtes et réponses en transit — clés API, tokens, clés privées, tout ce qui ressemble à un identifiant — et les expédie vers l’infrastructure de l’attaquant.
AC-1.a : injection ciblée par dépendance (variante adaptative d’AC-1). L’injection ne se déclenche que lorsque la requête correspond à une dépendance ou à un contexte spécifique — par exemple, uniquement lorsque la requête concerne une bibliothèque particulière, uniquement lorsqu’une fonction spécifique est référencée, uniquement lorsque certains chemins de fichiers apparaissent dans le prompt. Cela rend l’attaque invisible dans les tests aléatoires.
AC-1.b : livraison conditionnelle (variante adaptative d’AC-1). La charge utile malveillante est livrée sous des conditions spécifiques (heure de la journée, cadence des requêtes, empreinte client). Même logique d’évasion de détection.
Chacune de ces classes d’attaque est invisible pour le client et pour le modèle en amont, parce que les deux extrémités font confiance au routeur. Le client voit une forme de réponse normale. Le modèle voit une forme de requête normale. Le routeur est libre de faire ce qu’il veut au milieu, et aucune des parties n’a de moyen cryptographique de détecter la falsification.1
Le motif de composition, une couche plus bas
Je continue d’écrire sur le même bug structurel : des composants autorisés individuellement se composant en un comportement non autorisé. Trivy-to-LiteLLM était une composition à la couche des paquets. L’egress silencieux était une composition à la couche des descriptions d’outils. L’empoisonnement d’outils MCP était une composition à la couche protocole. La compromission du mainteneur d’axios était une composition à la couche du mainteneur humain.
L’attaque du routeur est une composition à la couche réseau. Votre client est autorisé à appeler le routeur. Le routeur est autorisé à appeler le modèle en amont. Le modèle en amont est autorisé à répondre. Chaque saut est autorisé. La composition de ces sauts autorisés produit une injection de charge utile et une exfiltration de secrets à grande échelle parce que la composition traverse une frontière de confiance que personne ne s’est donné la peine de sceller cryptographiquement.1
Vous ne pouvez pas corriger cela à une seule couche. Vous le corrigez à la couche de composition, ce qui signifie que le client doit traiter le routeur comme hostile jusqu’à ce qu’il ait vérifié indépendamment que la forme de la réponse, les appels d’outils et le contenu sont tous cohérents avec quelque chose que le modèle en amont produirait de manière plausible.
Trois défenses évaluées par le papier
Le papier évalue trois défenses côté client contre les classes d’attaque.1
1. Porte de politique fail-closed. Le client applique une politique sur les formes de réponse, les appels d’outils autorisés, les URL autorisées, les commandes autorisées. Tout ce qui est en dehors de la politique échoue en mode fermé — la requête est rejetée plutôt qu’autorisée.
2. Dépistage d’anomalies côté réponse. Le client surveille les anomalies de forme de réponse, les motifs de tokens inhabituels, ou les sorties contenant des marqueurs d’attaque connus (URL vers des hôtes inconnus, motifs d’identifiants suspects, structures d’appels d’outils inhabituelles).
3. Journalisation de transparence en ajout uniquement. Le client écrit chaque requête et réponse dans un journal en ajout uniquement qui ne peut pas être modifié rétroactivement. Cela n’empêche pas les attaques mais les rend traçables d’un point de vue forensique.
Aucune de ces défenses n’est une solution miracle. Mon interprétation : la porte de politique fail-closed est la plus forte des trois parce qu’elle ne repose pas sur la détection d’une attaque — elle rejette tout ce qui est en dehors d’une liste blanche explicite — mais le résumé ne classe pas les défenses, donc considérez cela comme mon opinion, pas comme un constat du papier. Le dépistage d’anomalies manque les attaques qui paraissent normales, et les variantes d’évasion adaptative (AC-1.a et AC-1.b) sont spécifiquement conçues pour paraître normales dans les conditions de test. Les portes de politique ne valent que ce que vaut la politique, et écrire une politique complète pour « à quoi devrait ressembler une réponse de modèle » est difficile.
Ce que vous devriez réellement faire
Si vous exécutez un agent qui appelle des APIs LLM à travers un routeur que vous n’avez pas construit :
-
Arrêtez d’utiliser des routeurs que vous avez achetés ou récupérés auprès de communautés publiques sauf si vous faites confiance à l’opérateur. « Confiance » signifie ici que vous avez une base externe — une équipe connue, un contrat signé, une juridiction légale contre laquelle vous pouvez agir — et non « il a de bons avis sur une place de marché ».
-
Ajoutez une porte de politique fail-closed à votre harnais. Dans Claude Code, cela signifie des hooks PreToolUse qui rejettent les appels d’outils en dehors d’une liste blanche explicite, et des hooks PostToolUse qui valident les formes de réponse avant de les transmettre au prochain tour du modèle. La pile de hooks est votre couche de politique fail-closed.
-
N’exécutez jamais le mode YOLO à travers un routeur que vous ne contrôlez pas. Les 401 sessions autonomes dans le pot de miel sont le précédent. Si le routeur est hostile et que votre session est autonome, le routeur exécute votre machine.
-
Journalisez tout. La journalisation de transparence en ajout uniquement est ce qui vous permet de reconstruire un incident. Chaque requête. Chaque réponse. Chaque appel d’outil. Stockez-les quelque part où le routeur ne peut pas atteindre.
-
Si vous exploitez une infrastructure d’agents, appliquez l’intégrité cryptographique. Si vous exploitez le client et l’amont, signez la requête sur le client et vérifiez la signature sur l’amont. C’est la seule véritable solution. Le routeur peut toujours voir le texte en clair, mais il ne peut rien modifier sans invalider la signature.
L’implication inconfortable
La surface d’attaque du routeur est un exemple net de l’écosystème d’agents livrant l’infrastructure plus vite qu’il ne la sécurise. Les gens veulent une clé API unique pour chaque modèle. Les gens veulent de l’arbitrage de prix. Les gens veulent un accès régional. Les routeurs livrent tout cela. Le marché les récompense. L’audit de sécurité n’a pas eu lieu.
La surface d’attaque MCP a 50 vulnérabilités documentées. La surface d’attaque de la chaîne d’approvisionnement a une campagne TeamPCP qui a traversé cinq écosystèmes en une semaine. La surface d’attaque de l’egress silencieux a Clinejection et le benchmark MCPTox. Ajoutez maintenant la surface d’attaque du routeur : 428 routeurs étudiés, 9 injectant activement du code malveillant, 17 touchant à des identifiants plantés, 1 vidant l’ETH, 401 sessions autonomes déjà en direct sur une infrastructure hostile.1
Le motif est le même à chaque fois. Nous construisons une nouvelle couche de la pile d’agents. La nouvelle couche est adoptée avant d’être auditée. Les attaquants arrivent. Les chercheurs arrivent. La communauté rédige les constats. Les opérateurs qui étaient attentifs patchent leurs déploiements. Les opérateurs qui n’étaient pas attentifs l’apprennent à leurs dépens.
La surface d’attaque du routeur en est au stade « les chercheurs viennent de la décrire ». Vous avez le temps de patcher votre déploiement. Utilisez-le.
FAQ
Qu’est-ce qu’un routeur LLM API dans ce contexte ?
Un service tiers qui se place entre votre client et les fournisseurs de modèles en amont, expose une API compatible OpenAI, et dispatche vos requêtes vers un ou plusieurs modèles en amont. C’est un proxy de couche applicative avec un accès en clair à chaque requête et réponse.1
En quoi est-ce différent d’un CDN ou d’un proxy HTTP classique ?
Un CDN transfère des octets sans lire la charge utile applicative. Un routeur LLM API lit la JSON, choisit un amont, réécrit éventuellement la requête, la transmet, lit la réponse, et réécrit éventuellement la réponse. Il effectue un traitement de niveau applicatif sur vos données, et non un simple transport.1
TLS me protège-t-il d’un routeur malveillant ?
Non. TLS protège les octets de votre client vers le routeur et du routeur vers le modèle en amont. Le routeur termine TLS, lit le texte en clair, et rechiffre de l’autre côté. TLS ne fait rien pour protéger votre charge utile contre le routeur.1
Comment pourrais-je détecter un routeur qui injecte activement des réponses ?
Vous ne le pourriez pas, de manière fiable, si le routeur utilise l’évasion adaptative. Les classes d’attaque AC-1.a et AC-1.b du papier ciblent spécifiquement l’évasion de détection en ne se déclenchant que dans des conditions opérationnelles.1 Votre meilleur pari est une porte de politique fail-closed — rejetant tout ce qui est en dehors d’une liste blanche explicite — plutôt que de tenter de détecter les attaques après coup.
J’exécute Claude Code directement contre api.anthropic.com. Suis-je concerné ?
Pas par la classe d’attaque de routeur décrite dans ce papier, parce que vous appelez Anthropic directement sans intermédiaire. La surface d’attaque concerne spécifiquement les routeurs tiers. Si vous acheminez Claude Code à travers un proxy pour une raison quelconque — passerelle d’entreprise, contournement de limitation de débit, agrégateur de modèles — vous devriez auditer ce proxy.
Qu’en est-il d’OpenRouter, LiteLLM, ou d’autres agrégateurs bien connus ?
Le papier étudie 28 routeurs payants achetés sur des places de marché spécifiques (Taobao, Xianyu, boutiques hébergées par Shopify) et 400 routeurs gratuits issus de listes communautaires publiques.1 Il ne publie pas de liste spécifique de produits nommés. Le point du papier est structurel : tout routeur est un intermédiaire non fiable sauf si vous avez une base de confiance distincte. Les agrégateurs bien connus ne sont pas automatiquement plus sûrs — ils sont simplement plus visibles, ce qui est une propriété différente.
Que devrais-je faire au sujet des 401 sessions autonomes que les chercheurs ont trouvées ?
Ces sessions appartiennent à d’autres opérateurs qui ont acheminé leur trafic à travers les leurres des chercheurs. Si vous exécutez des sessions d’agents autonomes à travers un routeur que vous n’avez pas construit, la première étape est d’arrêter. La deuxième étape est de faire tourner chaque identifiant qui a transité par ce routeur. La troisième étape est d’auditer vos journaux de session à la recherche d’appels d’outils ou de sorties anormaux.
Références
-
Hanzhi Liu, Chaofan Shou, Hongbo Wen, Yanju Chen, Ryan Jingyang Fang, « Your Agent Is Mine: Measuring Malicious Intermediary Attacks on the LLM Supply Chain », arXiv:2604.08407, avril 2026. Source principale pour toutes les données d’attaque de routeur, les définitions de classes d’attaque, la méthodologie d’étude de terrain et l’évaluation des défenses dans ce billet. Toutes les statistiques (28 routeurs payants, 400 routeurs gratuits, 1+8 injectant activement, 2 déclencheurs d’évasion adaptative, 17 touchant à des identifiants canary AWS, 1 vidant l’ETH, 100M de tokens d’une clé divulguée, 2 milliards de tokens de leurres, 401 sessions YOLO autonomes, 440 sessions Codex, 99 identifiants, taxonomie de deux classes d’attaque fondamentales — AC-1 injection de charge utile et AC-2 exfiltration de secrets — plus deux variantes d’évasion adaptative AC-1.a et AC-1.b, le proxy Mine implémente « les quatre classes d’attaque » contre quatre frameworks d’agents publics, trois défenses côté client : porte de politique fail-closed, dépistage d’anomalies côté réponse, journalisation de transparence en ajout uniquement) sont tirées directement du résumé du papier. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩