En-tête négligent

Quand les GPT personnalisés deviennent des portes dérobées pour le cloud : Le piratage du ChatGPT SSRF et l'avenir de la sécurité de l'IA

Si l'on reste suffisamment longtemps dans le domaine de la sécurité, on finit par prendre une mauvaise habitude : on cesse de voir les "caractéristiques" et on commence à voir les voies d'attaque potentielles. L'histoire récente de "ChatGPT hacked using Custom GPTs exploiting an SSRF vulnerability to expose secrets" (ChatGPT piraté à l'aide de GPT personnalisés exploitant une vulnérabilité SSRF pour exposer des secrets) en est un exemple classique. Ce qui semblait être une fonctionnalité d'actions pratique pour les GPT personnalisés s'est avéré être un tunnel direct dans l'environnement en nuage d'OpenAI. Pas de sorcellerie exotique, pas de "magie de l'IA" qui tourne mal - juste un très vieux bug, une falsification de requête côté serveur, redécouvert dans une toute nouvelle plateforme.

C'est précisément la raison pour laquelle cet incident est important. Il ne s'agit pas d'un autre titre à la mode sur l'IA qui se déchaîne. Il nous rappelle qu'une fois les LLM intégrés dans une infrastructure réelle, les règles traditionnelles de sécurité des applications et du cloud reviennent en force. Les modèles sont peut-être nouveaux, mais les erreurs sous-jacentes ne le sont pas.

Reconstruction de l'exploit : de "Add Action" à "cloud token

Pour comprendre ce qui s'est passé, il faut examiner le fonctionnement des GPT personnalisés. L'interface d'OpenAI vous permet de définir des actions, qui sont essentiellement des API HTTP externes que votre GPT peut appeler sur la base d'un schéma OpenAPI. Pour les utilisateurs, cela revient à donner à votre GPT des "superpouvoirs" : il peut récupérer des données, déclencher des flux de travail, se connecter à des systèmes internes. Sous le capot, cela signifie qu'il existe un client HTTP dorsal, fonctionnant dans l'infrastructure d'OpenAI, qui appellera volontiers les URL que vous décrivez et réinjectera les réponses dans le modèle.

C'est exactement ce qu'a remarqué un chercheur d'Open Security. En jouant avec des GPT personnalisés, ils ont vu le schéma familier : des URL contrôlées par l'utilisateur, un bouton "Test" qui envoie des requêtes en direct et un serveur qui fonctionne clairement dans un environnement en nuage. Toute personne ayant effectué des tests d'intrusion dans un environnement cloud reconnaîtra l'instinct qui en découle : vérifier si vous pouvez tromper ce serveur pour qu'il appelle des adresses internes en votre nom. C'est l'essence même du SSRF.

Dans les environnements en nuage, la cible interne la plus prisée est presque toujours le service de métadonnées. Sur Azure, comme sur d'autres clouds, il se trouve à l'adresse link-local 169.254.169.254. À l'intérieur d'une VM ou d'un conteneur, ce point d'extrémité peut révéler des détails sur l'instance et, plus important encore, émettre des jetons de courte durée qui permettent aux charges de travail d'appeler les API de gestion du nuage. Depuis l'extérieur du nuage, vous ne pouvez pas l'atteindre. C'est précisément la raison pour laquelle SSRF est si important : vous détournez le point d'observation du serveur et le forcez à parler à des choses que vous, en tant qu'attaquant externe, ne pouvez pas atteindre.

Le premier obstacle rencontré par le chercheur était que les Custom GPT Actions n'autorisaient que les URL HTTPS, alors que le service de métadonnées est uniquement HTTP. À première vue, cette restriction semble être un moyen de défense, mais en pratique, il s'agit d'une pièce de puzzle supplémentaire. La solution de contournement était simple : enregistrer un domaine HTTPS externe sous le contrôle du chercheur, le faire répondre par une redirection 302 pointant vers l'URL de l'action Custom GPT. http://169.254.169.254 et voir si le backend Actions a suivi la redirection. C'est le cas. Soudain, un appel HTTPS d'apparence innocente dans la configuration GPT personnalisée s'est traduit par un appel HTTP vers le point de terminaison interne des métadonnées du nuage.

Le service de métadonnées d'Azure n'est cependant pas complètement naïf. Pour éviter les abus, il exige un en-tête spécial, Métadonnées : trueà chaque demande. Si l'en-tête est manquant, le service refuse de divulguer des données réelles. À ce stade, on pourrait penser que le système est à nouveau sûr, car l'interface de schéma OpenAPI utilisée pour définir les actions n'expose pas la configuration arbitraire des en-têtes. Mais les grands systèmes ont rarement une seule surface de configuration. Dans ce cas, la fonctionnalité Actions prend également en charge l'idée de "clés API" et d'autres en-têtes d'authentification que vous pouvez définir lors du câblage d'un service externe. Ces en-têtes sont alors attachés automatiquement aux requêtes sortantes.

Cela a suffi pour compléter la chaîne. En définissant une fausse "clé API" dont le nom d'en-tête était littéralement Métadonnées et dont la valeur était vraiLe chercheur a convaincu le backend d'inclure l'en-tête exact attendu par Azure IMDS. Combinez cela avec l'astuce de la redirection et vous avez maintenant un canal SSRF depuis le backend Custom GPT Actions vers le service de métadonnées, avec une adresse Métadonnées : true l'en-tête.

Une fois ce canal établi, le reste était presque mécanique. Le chercheur a demandé au service de métadonnées un jeton OAuth2 destiné à l'API de gestion Azure, en utilisant le chemin IMDS bien connu. La réponse contenait un jeton d'accès lié à l'identité cloud utilisée par l'infrastructure ChatGPT. Ce jeton pouvait, au minimum, interroger les points finaux de gestion et potentiellement atteindre des ressources sensibles, en fonction du niveau de privilège de l'identité. À ce stade, le chercheur s'est arrêté, a signalé ses découvertes par l'intermédiaire du programme de primes aux bogues de l'OpenAI, et l'OpenAI a classé la faille comme étant de haute sévérité et a entrepris de la corriger.

Ce qui rend cette chaîne frappante, c'est que l'attaquant n'a jamais eu besoin d'un accès au shell, de code source ou d'un bogue classique dans la pile HTTP. Tout s'est passé à l'intérieur d'écrans de configuration normaux : URL, paramètres d'authentification et bouton de test qui exécute consciencieusement le méfait.

Sécurité de l'IA Penligent

Une petite esquisse de code d'une sonde de type SSRF

Pour rendre cela plus concret, imaginons un tout petit script d'aide interne qu'un ingénieur en sécurité pourrait utiliser pour vérifier le bien-fondé d'un client HTTP de type "Actions". L'objectif n'est pas de toucher les services de métadonnées réels en production, mais de codifier l'habitude de rechercher des redirections inattendues et des sauts d'IP internes dans les environnements d'essai ou de laboratoire :

import requests
from urllib.parse import urljoin

def trace_request(base_url : str, path : str = "/") :
    url = urljoin(base_url, path)
    print(f"[+] Requesting {url}")
    try :
        resp = requests.get(url, timeout=3, allow_redirects=True)
    except Exception as e :
        print(f"[ !] Error : {e}")
        return

    print(f"[+] Final URL : {resp.url}")
    print(f"[+] Statut : {resp.status_code}")
    print("[+] Chaîne de redirection :")
    for h in resp.history :
        print(f" {h.status_code} -> {h.headers.get('Location')}")

    # Heuristique très grossière : avertir si l'on tombe sur une IP interne
    if resp.raw._connection and hasattr(resp.raw._connection, "sock") :
        peer = resp.raw._connection.sock.getpeername()[0]
        print(f"[+] Peer IP : {peer}")
        if peer.startswith("10.") or peer.startswith("192.168.") or peer.startswith("169.254.") :
            print("[ !] Warning : backend followed a redirect into an internal address")

if __name__ == "__main__" :
    # Exemple : remplacer par un point de terminaison de test contrôlé dans votre propre laboratoire
    trace_request("")

Un script comme celui-ci n'exploite pas ChatGPT, mais il capture la même forme d'investigation : commencer à partir d'une URL externe supposée sûre, suivre les redirections et se plaindre bruyamment si votre client HTTP se retrouve soudainement à parler à des plages d'IP internes ou locales au lien. Transformer ce modèle en automatisation - et l'appliquer aux composants qui alimentent vos propres actions d'IA - est bien plus utile que de se contenter de lire l'incident.

Il ne s'agit pas d'un "bug de l'IA", mais d'un abus de nuage à l'ancienne qui prend une nouvelle dimension.

Il est très tentant de lire cela comme "ChatGPT a été piraté" et de passer à autre chose. Ce cadrage passe à côté de la leçon la plus profonde. Rien dans le modèle lui-même ne s'est mal comporté. Il n'y a pas eu d'invite qui a débloqué des capacités interdites. Le LLM a fait ce qu'on lui a demandé : appeler une action, lire le résultat et le résumer. La vulnérabilité résidait entièrement dans la colle entre le LLM et le monde extérieur.

C'est précisément sur cette colle que les équipes de sécurité doivent se concentrer. Chaque fois que vous donnez à un LLM la possibilité d'appeler des outils, des actions ou des plugins, vous le transformez effectivement en un client programmable dans votre infrastructure. Auparavant, un utilisateur appelait manuellement votre API et vous examiniez ses données. Désormais, un utilisateur donne des instructions à un modèle, qui les traduit en appels d'API en son nom. Le modèle devient un autre moyen pour l'intention hostile d'atteindre votre backend.

Vu sous cet angle, cet incident n'est rien d'autre que le SSRF de l'OWASP dans un costume différent. Les conditions sont toutes familières : des URL influencées par l'utilisateur, un serveur qui peut atteindre des points de terminaison internes ou privilégiés, des contrôles de sortie manquants ou incomplets, et un service de métadonnées dans le nuage trop accessible pour les charges de travail normales. La différence est que le point d'entrée n'est plus un formulaire web classique ou un champ JSON ; c'est un bloc de configuration qui a été conçu pour rendre les Custom GPT plus puissants.

C'est également la raison pour laquelle le rayon de l'explosion est important. Le serveur affecté n'était pas un microservice aléatoire ; il faisait partie de l'infrastructure multi-tenant de ChatGPT, située dans l'environnement Azure d'OpenAI. Tout jeton obtenu via IMDS appartenait à une charge de travail qui disposait déjà d'un accès significatif. Même si les défenses locales limitaient ce que l'attaquant pouvait faire, le profil de risque était fondamentalement différent de celui d'une VM de test oubliée.

L'IA comme plaque tournante de l'intégration : élargir les surfaces d'attaque et déplacer les frontières de la confiance

L'histoire la plus intéressante qui se cache derrière ce bogue est d'ordre architectural. Les plateformes d'IA deviennent rapidement des centres d'intégration. Un GPT personnalisé pour une équipe de vente peut communiquer avec un CRM, un système de facturation et un magasin de documents. Un GPT axé sur la sécurité peut communiquer avec des scanners, des systèmes de billetterie et CI/CD. Dans chaque cas, le LLM n'est pas l'actif, ce sont les données et les actions derrière ces connecteurs qui le sont.

Une fois cette réalité acceptée, votre modèle mental de menace doit changer. Vous ne pouvez pas continuer à penser que la "sécurité de l'IA" se limite à l'injection rapide, à la fuite de données ou aux résultats toxiques. Vous devez également poser des questions profondément ingrates sur les limites du réseau, l'identité du cloud et l'isolement des locataires.

À quoi l'infrastructure qui exécute vos actions peut-elle réellement s'adresser sur le réseau ? Dans de nombreux environnements en nuage, la valeur par défaut est "tout ce qui sort est autorisé tant que le DNS est résolu". Cela avait du sens lorsque les services étaient relativement simples et que les ingénieurs voulaient de la flexibilité. Cependant, si l'on place une plateforme LLM au milieu, chaque locataire dispose soudain d'un moyen de proposer de nouvelles destinations sortantes par le biais de la configuration, plutôt que par le code. S'il n'y a pas de politique de sortie forte, vous avez effectivement créé un lanceur de SSRF programmable.

Quel est le degré de privilège des identités utilisées par ces charges de travail ? Dans le cas de ChatGPT, les chercheurs ont pu demander un jeton pour l'API de gestion Azure. Même si ce jeton était limité par l'attribution de rôles, il représente toujours un secret de grande valeur. Dans de nombreuses organisations, la tentation est grande d'accorder de larges autorisations à l'"infrastructure de la plateforme", car cela simplifie le déploiement. Pour tout ce qui peut être piloté indirectement par l'utilisateur, en particulier par l'IA, cette tentation est dangereuse.

Où se situent exactement les limites de la confiance entre les locataires, entre le plan de contrôle et le plan de données, et entre le moteur d'exécution de l'IA et le reste du nuage ? Un système bien conçu doit partir du principe que la configuration d'un locataire peut devenir hostile, que tout appel sortant au nom de ce locataire peut être hostile et que toute élévation de l'action aux métadonnées et aux API de gestion est un objectif réaliste de l'attaquant. Cette perspective rend les modèles tels qu'une segmentation stricte du réseau, des sidecars compagnons appliquant des politiques et des identités de service dédiées non négociables plutôt qu'"agréables à avoir".

D'un incident à une méthodologie de test reproductible

Pour les défenseurs et les constructeurs, la valeur réelle de cette histoire n'est pas le bogue spécifique ; c'est l'état d'esprit de test qu'elle illustre. Le chercheur a essentiellement traité les Custom GPT Actions comme un nouveau type étrange de client HTTP et a ensuite procédé à une liste de contrôle familière : puis-je contrôler l'URL, puis-je atteindre des hôtes internes, puis-je abuser des redirections, puis-je injecter des en-têtes, puis-je toucher des métadonnées, puis-je transformer cela en un jeton de nuage ?

Cette liste de contrôle mentale est exactement ce qui devrait être automatisé dans les flux de travail des tests de pénétration modernes pour les plateformes d'IA. Au lieu d'attendre un gros titre et un rapport de bounty, les équipes devraient régulièrement transformer leur propre infrastructure Custom GPT, leurs écosystèmes de plugins et leurs chaînes d'outils en cibles.

Pour rendre cela un peu plus tangible, vous pouvez considérer qu'un "examen du SSRF des actions de l'IA" est une séquence simple et répétable comme celle-ci :

PhaseQuestion cléExemple dans le cas du ChatGPT
Influence de l'URLLe locataire peut-il contrôler l'URL de manière significative ?Les actions GPT personnalisées permettent à l'utilisateur de définir des points d'extrémité externes.
Comportement de redirectionSuivons-nous les redirections vers des sites inconnus ?Point de terminaison HTTPS redirigé vers 169.254.169.254.
Manipulation de l'en-têteLe locataire peut-il définir indirectement des en-têtes sensibles ?Configuration de la clé API utilisée pour injecter Métadonnées : true.
Privilèges et jetonsQue peut faire un jeton obtenu ?L'IMDS a émis un jeton d'API de gestion pour la charge de travail.

Une fois ce type de tableau établi pour votre environnement, il devient beaucoup plus facile d'automatiser et d'expliquer les tests que vous effectuez. Vous pouvez l'intégrer dans les playbooks internes, le partager avec les fournisseurs et veiller à ce que les futures fonctionnalités d'IA soient soumises à la même norme.

C'est là que les outils de sécurité spécialisés et dotés d'une intelligence artificielle commencent à prendre de l'importance. Un scanner web générique pourrait ne pas savoir comment naviguer dans une interface utilisateur qui cache les appels réseau derrière des actions ou comment raisonner sur les schémas OpenAPI utilisés dans une définition GPT. En revanche, une plateforme de pentest pilotée par l'IA telle que Penligent peut traiter ces schémas et configurations comme des entrées de première classe. Vous pouvez imaginer un flux de travail dans lequel vous exportez la configuration des Actions pour un ensemble de GPT personnalisés ou d'autres outils d'IA, les introduire dans un pipeline de test agentique, et le laisser systématiquement rechercher des conditions SSRF, des redirections non sûres, des accès réseau non limités, et l'exposition des métadonnées.

La philosophie de Penligent, qui consiste à combiner l'automatisation et le contrôle humain dans la boucle, correspond bien à ce modèle. Un agent peut énumérer toutes les définitions d'outils, générer des charges utiles candidates pour les points de terminaison qui acceptent des URL ou des noms d'hôtes, et conduire un trafic scénarisé qui simule ce qu'un attaquant curieux essaierait. Lorsque le système découvre un comportement prometteur - par exemple, qu'un point d'extrémité HTTPS apparemment externe suit des redirections vers des plages d'adresses IP internes - il peut le présenter comme une preuve : journaux de requêtes, extraits de réponses et topologie interne déduite. Un opérateur humain peut alors orienter les étapes suivantes, par exemple en demandant au système de s'orienter spécifiquement vers les routes de métadonnées du nuage ou de vérifier si les jetons renvoyés sont valides par rapport aux API de gestion.

Ce type de flux de travail permet d'accomplir deux choses. Il intègre les plateformes d'IA dans la même boucle de sécurité basée sur les preuves que les applications web et les API, et il exploite les mêmes capacités LLM que les attaquants utiliseront inévitablement, mais au service des défenseurs. Le bogue qui a touché ChatGPT n'est alors plus une surprise ponctuelle ; il devient un cas de test dans une suite de régression que vous pouvez exécuter chaque fois que vous introduisez une nouvelle intégration ou que vous modifiez votre infrastructure d'actions.

Enseignements pratiques pour les équipes qui développent des plateformes d'IA

Si vous êtes un ingénieur ou un architecte en sécurité qui consomme des services d'IA plutôt que de les créer, cet incident est toujours d'actualité. Même si vous ne touchez jamais aux GPT personnalisés en interne, vous exposez probablement des API internes, des tableaux de bord ou des magasins de documents à des agents d'IA ou à des copilotes d'une sorte ou d'une autre. Les idées sont transférables.

La première étape consiste à cesser de considérer le LLM comme la seule chose qui nécessite un examen de sécurité. Toute fonctionnalité qui permet aux modèles de rappeler votre environnement - que ce soit par le biais d'outils explicites, d'actions ou de webhooks indirects - doit être considérée comme un graphe d'attaque potentiel. Vous devriez être en mesure de répondre, avec une certaine confiance, aux services internes auxquels un composant d'IA peut s'adresser, aux identités qu'il utilise et à ce qui se passe si un utilisateur hostile tente délibérément d'étendre ces capacités.

La deuxième étape consiste à étendre vos programmes de test pour couvrir le code de collage de l'IA. Lorsque vous commandez un test de pénétration ou que vous organisez un exercice interne de l'équipe rouge, assurez-vous que le champ d'application inclut explicitement les intégrations de l'IA : les surfaces de configuration des outils, la façon dont les URL et les en-têtes sont construits, les chemins de réseau entre les moteurs d'exécution de l'IA et les services sensibles, et les protections autour des points de terminaison des métadonnées. Demandez des preuves que quelqu'un, quelque part, a essayé d'abuser de ces éléments comme le ferait un véritable attaquant.

La troisième étape consiste à accepter que cette surface d'attaque ne se réduira pas. Comme de plus en plus de processus d'entreprise se connectent aux LLM, il y aura plus d'actions, plus de plugins, plus de services d'arrière-plan qui travailleront pour le compte des invites. Vous pouvez soit intégrer la sécurité comme une série de correctifs liés à des incidents, soit construire un programme reproductible : des modèles de menace clairs, des modèles d'architecture de base, des flux de tests automatisés et des outils - potentiellement alimentés par des systèmes tels que Penligent - qui continuent à sonder au fur et à mesure que votre environnement évolue.

Au-delà du titre

Le hack Custom GPT SSRF est facile à interpréter comme un embarras ponctuel pour un seul fournisseur. Il est plus productif de le lire comme un aperçu. Les plateformes d'IA se transforment rapidement en couches d'orchestration qui relient les utilisateurs, les modèles, les API et l'infrastructure cloud. Ce rôle s'accompagne de puissance, et la puissance s'accompagne toujours d'un plus grand rayon d'explosion lorsque quelque chose ne va pas.

L'aspect encourageant de cette histoire est qu'elle montre également la voie à suivre. La vulnérabilité a été découverte par un chercheur qui a suivi ses anciens instincts dans un nouveau contexte. Elle a été signalée par le biais d'un canal standard de recherche de bogues. Elle a été corrigée. Le reste d'entre nous peut maintenant prendre le même manuel et l'appliquer de manière proactive à nos propres systèmes, idéalement avec l'aide d'outils qui comprennent à la fois la sécurité et l'IA.

Si nous faisons cela, alors l'héritage de cet incident n'est pas seulement "ChatGPT a un jour eu un SSRF". Il devient une étude de cas sur la façon de penser la sécurité de l'IA : traiter les modèles comme un composant d'un système plus large, traiter les intégrations comme des surfaces d'attaque sérieuses, et utiliser l'automatisation plus la perspicacité humaine - que ce soit par le biais de plateformes comme Penligent ou de vos propres pipelines internes - pour transformer continuellement une vague inquiétude en une assurance concrète, testable et étayée par des preuves. C'est le genre d'histoire qui vaut la peine d'être racontée sur Medium, et qui vaut encore plus la peine d'être vécue au sein de votre organisation d'ingénierie.

Partager l'article :
Articles connexes
fr_FRFrench