Illustration technique abstraite sur un fond ardoise profond : une étroite colonne de serveur de documentation, à gauche, fait passer de petites cartes rectangulaires le long d’un canal éclairé vers un unique nœud d’agent, à droite, qui porte un anneau de petits objets en forme de clé. L’une des cartes est bordée d’ambre et porte une faible silhouette de clé reproduite en miroir dans l’anneau de l’agent. Derrière la colonne se trouve une grille lâche d’entrées de bibliothèque, dont l’une est ombrée plus sombre que les autres. De fines lignes turquoise divisent le canal en segments de livraison. Aucune personne, aucun logo, aucun lettrage d’aucune sorte. Le logo OrcaRouter est intégré dans le coin inférieur droit.
AI Safety Incidents

CVE-2026-75130 : le serveur de documentation MCP de Context7 obtient un score de 9,0, et l’avis ne mentionne aucune version corrigée

Auteur

Alistair Wren

Date de publication

Derniers modèles · 20Voir tous les modèles →
Benchmarks : Artificial Analysis · mis à jour quotidiennement
Retour à tous les articles

Le 18 août 2026, VulnCheck a publié CVE-2026-75130 visant Context7, le serveur de documentation de bibliothèques qu’Upstash exploite pour le Model Context Protocol et que les agents de codage interrogent pour obtenir de la documentation propre à une version. La faille réside dans la fonctionnalité qu’Upstash appelle Custom AI Instructions : le propriétaire d’une bibliothèque joint des consignes à une entrée de documentation, Context7 injecte ces consignes dans la fenêtre de contexte de chaque agent qui consulte la bibliothèque, et rien sur ce parcours ne les assainit. Noma Security, dont Eli Ainhorn, chercheur principal en vulnérabilités liées à l’IA, est crédité de la découverte, a démontré qu’une entrée empoisonnée peut amener un agent connecté à lire les fichiers .env à la racine du projet, à envoyer leur contenu dans un dépôt GitHub contrôlé par l’attaquant sous la forme d’un ticket, et à supprimer des dossiers locaux sous prétexte de « nettoyage » — le tout à partir d’une demande de documentation de routine. Aucune victime n’est enregistrée. Le reste des incidents documentés impliquant des agents, chacun avec sa propre gravité, son niveau de confiance et son indicateur de contestation, se trouve dans l’archive des incidents liés à l’IA, où les entrées voisines de cet enregistrement peuvent être lues à côté de celle-ci.

Le serveur de Context7 est petit, et c'est la partie qu'il faut comprendre en premier. L'article de Noma note qu'il expose deux outils, resolve-library-id et query-docs, et qu'il ne peut pas exécuter du code, écrire des fichiers ni accéder au réseau par lui-même. Chaque impact documenté est mis en œuvre par l'agent situé à l'autre bout, qui dispose bien d'un accès au système de fichiers, au shell et au réseau sur la machine du développeur. Le registre npm montre l'ampleur de la base installée : @upstash/context7-mcp a été téléchargé 4 064 176 fois au cours des trente jours du 22 juillet au 20 août 2026, la période autour de la publication.

Le mécanisme : une seule bibliothèque empoisonnée, tous les agents qui l'interrogent

La démonstration de Noma, décrite dans son article ContextCrush du 5 mars 2026, s'est déroulée en trois étapes exécutées par l'agent plutôt que par le serveur. Elle a enregistré une bibliothèque dans le registre de Context7 avec des règles empoisonnées attachées. Les instructions contenues dans ces règles demandaient à l'agent de rechercher et de lire chaque fichier .env à la racine du projet ; d'autres instructions lui demandaient de publier le contenu dans un dépôt GitHub contrôlé par l'attaquant sous forme de ticket ; une dernière série lui indiquait de supprimer les dossiers et fichiers locaux pour « nettoyage ». La requête qui fait entrer tout cela dans le contexte est ordinaire — demander à un assistant de codage de l'aide pour une bibliothèque.

La raison pour laquelle il s'agit d'un problème de chaîne d'approvisionnement plutôt que d'une injection de prompt ordinaire réside dans l'endroit où se trouve la charge utile. L'attaquant n'atteint jamais la machine de la victime et n'a jamais besoin de placer du texte dans un document que l'utilisateur ouvre. Les instructions empoisonnées se trouvent sur le propre registre de Context7, sont hébergées et servies par l'infrastructure propre de Context7, et arrivent par le même canal de confiance que la documentation légitime, indiscernables de celle-ci. Noma note que le score de confiance de Context7, qui évalue les bibliothèques en fonction de l'historique GitHub qui les sous-tend, ne protège pas contre cela, car un compte de longue date peut être acheté, détourné ou fabriqué. Le résumé que l'entreprise fait elle-même de ce point structurel est sans détour : « La surface d'attaque ne réside pas dans ce que le serveur MCP peut faire. Elle réside dans ce qu'il peut amener l'agent IA à faire. »

Deux scores pour un seul bug

L'avis porte CVSS 3.1 9.0 (critique) et CVSS 4.0 6.4 (moyen). Les deux vecteurs ont été fournis par VulnCheck en tant que CNA attributrice, et le NVD reprend les deux sans modification, en attribuant chacun à VulnCheck. Cette divergence n'est pas une erreur ; elle vient de ce que les deux référentiels comptabilisent les mêmes dommages sur des machines différentes. CVSS 3.1 marque le champ Scope comme « Changed » — l'injection franchit la frontière du serveur vers la machine du développeur et au-delà — et inscrit donc à pleine pondération l'impact élevé complet sur la confidentialité, l'intégrité et la disponibilité des capacités de l'agent. CVSS 4.0 remplace le champ Scope par des métriques distinctes pour le système vulnérable et pour le système subséquent : il n'enregistre aucun impact sur la confidentialité, l'intégrité ou la disponibilité pour Context7 lui-même (VC:N/VI:N/VA:N) et un impact élevé sur les systèmes en aval (SC:H/SI:H/SA:H), que sa formule pondère moins lourdement. Le serveur est le messager, pas la victime.

La divergence se propage dans les bases de données. L'avis de GitHub, GHSA-97r6-3rgm-v39r, a été publié à 18:32 UTC le 18 août, une demi-heure après la CVE, et sa gravité indiquée dans le résumé est moyenne alors même que le vecteur CVSS 3.1 du même enregistrement obtient un score de 9,0. La base de données EU Vulnerability Database d'ENISA reprend l'entrée sous EUVD-2026-61099 et enregistre un score de base de 6,4 sous la version 4.0 uniquement. L'enregistrement d'archive que suit cet article attribue à l'incident une gravité élevée — qui ne correspond à aucun des deux scores publiés — et il s'agit de la notation de l'archive, et non d'une mesure qui lui soit propre.

HTML card titled 'One advisory, two scores', kicked 'OrcaRouter · AI incident archive · 2026-08-18', with the subtitle 'Identical facts, two severity bands apart. Both vectors were supplied by VulnCheck as the assigning CNA; NVD carries both unchanged and attributes each to VulnCheck'. Four chips read CVSS 3.1 9.0 critical, CVSS 4.0 6.4 medium, archive grade high and EPSS 0.49%. Three columns. 'Where the vectors agree' lists attack vector network with low complexity, privileges required low because the attacker needs a registry entry rather than the victim's machine, a routine documentation request as the trigger, and high confidentiality, integrity and availability impact in both frameworks. 'Where they diverge' lists CVSS 3.1 setting Scope to Changed and booking the jump to the developer's machine at full weight, CVSS 4.0 recording the vulnerable system as unharmed at VC:N, VI:N and VA:N, the same harms booked downstream at SC:H, SI:H and SA:H with less weight, and user interaction at required in 3.1 against passive in 4.0. 'How the databases record it' lists NVD keeping both vectors each tagged disclosure@vulncheck.com, GHSA-97r6-3rgm-v39r carrying a summary severity of medium while its own v3 vector reads 9.0, ENISA EUVD-2026-61099 storing 6.4 under version 4.0 only, and the archive grading the record high, which is neither score. A footer reads 'Sources: CVE-2026-75130 in the MITRE CVE Services record, 18 August 2026; NVD API; GitHub Advisory API; ENISA EUVD API. EPSS as recorded in ENISA's mirror.'

Une CVE publiée en août pour une divulgation en mars

L'identifiant CVE a été réservé le 17 août 2026 et publié le 18 août à 18:02 UTC, soit la date portée par l'enregistrement. Le conteneur CNA comporte également une seconde date qui n'apparaît pas sur les pages de l'agrégateur : datePublic, 5 mars 2026 — cinq mois et demi avant que l'identifiant n'existe, et le jour même où Noma a publié ContextCrush. La seule référence technique de l'avis est cet article de mars, que VulnCheck étiquette à la fois comme description technique et comme exploit.

La chronologie de divulgation de Noma explique l’écart. Elle indique que la faille a été signalée à Upstash le 18 février 2026 avec un rapport complet et une preuve de concept, consigne qu’Upstash a accepté les conclusions et commencé la remédiation le 19 février, affirme qu’un correctif a été « déployé en production avec assainissement des règles et garde-fous » le 23 février, et fixe la divulgation publique et la vérification finale par Noma au 5 mars. Selon Noma, le bug de février a été résolu en quelques jours.

Les dates du registre npm concordent avec cette chronologie d’une manière qui donne à la plage affectée une apparence étrange. @upstash/context7-mcp 2.1.2a été publié le 23 février 2026 à 10:06 UTC, le jour où, selon Noma, le correctif a atteint la production ; la ligne de son changelog indique « Supprimer l’avertissement inutile et mettre à jour les descriptions des outils. » 2.1.3a suivi le 4 mars 2026, la veille de l’article de Noma, avec des notes sur le rejet des requêtes GET sur les points de terminaison MCP et l’ajout d’un champ source aux résultats de recherche. Aucune des deux notes de version ne mentionne l’assainissement, les garde-fous ou l’injection. La plage affectée de la CNA se termine à 2.1.2, ce qui fait de 2.1.3 la première version en dehors de cette plage.

Trois interprétations correspondent à ces dates, et ni VulnCheck ni Noma n’indique laquelle est correcte. La première, défendue par Digital Applied dans son article du 18 août et reprise par AI Security Wire le 22 août, est que le correctif a régressé : la build qui contenait le patch de février se situe dans la plage affectée d’août. La deuxième est que la plage est simplement ancrée sur la build testée par le chercheur, et que 2.1.3, publiée la veille de la divulgation, constitue la véritable limite — une déduction que plusieurs agrégateurs font mécaniquement, dont Feedly, qui liste « mettre à jour vers la version 2.1.3 ou ultérieure » comme mesure d’atténuation. La troisième est que le correctif de février a été appliqué là où les règles sont servies plutôt que dans le paquet client, auquel cas une plage de versions npm ne décrit pas du tout le correctif. Un correctif de sécurité silencieux est assez courant pour que l’absence d’une entrée correspondante dans le journal des modifications ne tranche rien dans un sens ou dans l’autre.

HTML card titled 'Six months, one affected range', kicked '2026-08-18-context7-mcp-ti-shi-zhu · dates', subtitled 'Times UTC. Noma's disclosure timeline and the npm registry dates do not say what the 23 February fix changed, and no release note mentions sanitisation'. Four chips read 18 Feb 2026 reported to Upstash, 23 Feb 2026 fix live and npm 2.1.2, 5 Mar 2026 datePublic, and 18 Aug 2026 CVE published. Three columns. 'Noma's February timeline' lists 18 February discovery with the report and proof of concept delivered to Upstash, 19 February acceptance and remediation, 23 February deployment of a fix with rule sanitization and guardrails, and 23 February at 10:06 UTC the npm publication of 2.1.2 with a changelog reading 'Remove unnecessary warning and update tool descriptions'. 'The March boundary' lists 4 March at 12:51 UTC the npm publication of 2.1.3 whose changelog covers 405 handling for GET requests and a source field, 5 March publication of Noma's ContextCrush writeup with final verification, 5 March as the CNA's datePublic for the CVE, and the affected range ending at 2.1.2, which makes 2.1.3 the first build outside it. 'The August record' lists 17 August reservation of the identifier, 18 August at 18:02 UTC publication by VulnCheck as CNA, 18 August at 18:32 UTC the appearance of GHSA-97r6-3rgm-v39r with no version ranges, no fixed version in the CVE, the VulnCheck advisory or the GHSA, and NVD last modified 22 October at status Deferred with no CPE configurations. A footer reads 'Sources: MITRE CVE Services record for CVE-2026-75130; Noma Security, ContextCrush, 5 March 2026; npm registry version times; GitHub Advisory API; NVD API, read 29 October 2026.'

Ce qui est établi, et ce qui ne l’est pas

• Établi par l'enregistrement primaire. L'identifiant CVE, sa publication du 18 août, VulnCheck en tant que CNA, la classification CWE-1427 pour neutralisation inappropriée d'entrées utilisées pour le prompting LLM, le crédit attribué à Eli Ainhorn de Noma Security, et une plage affectée de Context7 jusqu'à la version 2.1.2.

• Établi par les recherches de Noma. Le chemin d’injection via la fonctionnalité Custom AI Instructions, la preuve de concept en trois étapes, l’observation que le serveur n’expose que resolve-library-id et query-docs, et l’affirmation qu’aucune preuve d’exploitation dans la nature n’a été observée pour le bug de février.

• Établi par le registre. La date de publication 2.1.2 du 23 février 2026, la date de publication 2.1.3 du 4 mars 2026, et une ligne de paquet qui a depuis dépassé 4.0 pour atteindre 4.4.4 le 19 octobre 2026.

• Non établi : si les builds actuels sont affectés. Aucune source n'indique que la branche 4.x est vulnérable, et aucune source n'indique qu'elle est exempte. L'enregistrement CVE, l'avis VulnCheck et l'avis GitHub ne mentionnent aucune version corrigée, et la liste des plages de versions vulnérables de l'avis GitHub est vide.

• Non établi : aucune victime ni utilisation en conditions réelles. L'archive consigne comme faux les préjudices réels. L'enrichissement de la fiche par la CISA le 19 août a noté l'Exploitation comme « aucune », l'Automatisabilité comme « non » et l'Impact technique comme « total » ; la faille ne figure pas dans le catalogue KEV ; le miroir de l'ENISA indique un EPSS de 0,49 pour cent. La recherche de Noma est une démonstration, pas un rapport d'incident.

• Non établi : la lecture en tant que régression elle-même. Elle repose sur une coïncidence de dates entre une chronologie de correction et une publication npm, et aucune source primaire n’affirme que le même chemin de code a échoué deux fois.

HTML card titled 'What the record establishes, and what it does not', kicked 'Evidence ledger · CVE-2026-75130', subtitled 'The archive grades this record confidence A, disputed false, real harm false, AI involvement confirmed. Those are its fields; this is what they rest on'. Four chips read confidence A, disputed false, real harm false, AI involvement confirmed. Three columns. 'Established by primary sources' lists CVE-2026-75130 published 18 August 2026 with VulnCheck as CNA and CWE-1427, credit to Eli Ainhorn of Noma Security, an affected range of Context7 through 2.1.2, the injection path and three-step proof of concept as Noma describes them, and npm dates of 2.1.2 on 23 February, 2.1.3 on 4 March and latest 4.4.4 on 19 October 2026. 'Not established' lists whether the 4.x line is vulnerable or clear with no source saying either way, whether February's fix regressed or was never in the client package, any victim or in-the-wild use with CISA's SSVC recording exploitation none and the flaw absent from KEV, and a fixed version, which the CVE, the VulnCheck advisory and the GHSA all leave unnamed. 'What corroborates it' lists VulnCheck's advisory restating the CVE and adding the weakness class and credit, GHSA-97r6-3rgm-v39r as an alias of the same submission thirty minutes later, ENISA EUVD-2026-61099 mirroring the record along with the CVE aggregator pages, and two secondary write-ups restating it with no newsroom coverage found on 29 October 2026. A footer reads 'Sources agree because the GitHub and ENISA entries derive from the same VulnCheck submission, not because a second party measured the flaw.'

Corroboration : reformulation et silence là où cela compte

Les documents qui concordent avec le dossier en sont largement dérivés. L'avis de VulnCheck reprend le texte de la CVE et y ajoute la classification de la faiblesse ainsi que le crédit au chercheur. L'avis GitHub est un alias de la même soumission, publié le même soir, sans plages de versions et sans examen indépendant. L'entrée d'ENISA est un miroir. Digital Applied, l'une des deux sources citées par l'archive, a publié son analyse le 18 août et l'a mise à jour le 22 août avec de nouvelles extractions du registre ; AI Security Wire a publié un second article le 22 août. Les deux reprennent l'avis et relayent l'inférence de régression, et aucun des deux ne prétend l'avoir vérifiée de façon indépendante.

Nous n’avons trouvé aucune couverture médiatique de la CVE le 29 octobre 2026 — aucun article de BleepingComputer, The Register ou SecurityWeek — et les résultats étaient des pages d’agrégateurs de CVE plutôt que des reportages. Cette absence compte pour la manière dont le dossier doit être lu : l’archive lui attribue la note A, bien documenté par des sources primaires concordantes, et les sources primaires concordent effectivement, mais la concordance ici s’établit entre une fiche CNA et les recherches qu’elle cite, non entre deux mesures indépendantes. Plusieurs pages d’agrégateurs ajoutent des affirmations que leurs sources n’étayent pas ; l’entrée de Feedly, par exemple, indique qu’un correctif est disponible et nomme la version 2.1.3, ce que ne fait aucun avis, tandis que la page de VulDB a renvoyé une vérification anti-bot au lieu de contenu et n’a pas pu être lue du tout.

Ce qui a changé, et ce qui n’a pas changé

Pour le bug de février, Upstash a réagi en quelques jours : accepté le 19 février, corrigé le 23 février, selon le compte de Noma. Pour le dossier d'août, la seule déclaration du fournisseur à laquelle la CVE fait référence est une publication LinkedIn d'Upstash, y étiquetée comme avis fournisseur, dont nous n'avons pas pu lire le contenu sans session. Aucun avis de sécurité GitHub portant sur le dépôt n'indique de version corrigée, et l'entrée NVD affiche le statut Différé sans configurations CPE et avec une dernière modification du 22 octobre 2026, de sorte que l'analyse propre à la NVD ne figure pas au dossier.

Le paquet lui-même a continué d’être publié. Entre le 20 avril 2025 et le 23 octobre 2026, le dépôt upstash/context7 a publié 163 versions, et aucune de leurs notes ne mentionne cette CVE ni ne décrit l’assainissement des instructions personnalisées qui véhiculent l’injection. C’est un témoignage de ce que les mainteneurs ont choisi de consigner, et non la preuve que rien n’a été corrigé.

Ce que le compte rendu laisse à un opérateur, c’est une gestion de l’exposition plutôt qu’une ligne de correctif. Les recommandations de Noma portent principalement sur l’examen des intégrations MCP et l’inspection de ce qui transite entre l’agent et le serveur à l’exécution ; les actions suggérées par OpenCVE sont de mettre à niveau, de désactiver ou de restreindre la fonctionnalité Custom AI Instructions, et d’ajouter une validation des entrées au serveur. La version opérationnelle de tout cela se résume aux mêmes trois mesures : épingler la version du serveur MCP au lieu de dépendre d’une version « latest » flottante, garder les identifiants de production hors des fichiers d’environnement en clair que l’agent peut lire, et traiter les réponses des outils comme des entrées non fiables plutôt que comme une documentation que l’agent pourrait suivre.

Dix semaines après la publication, le registre public s’arrête toujours là où il en était le 18 août : un identifiant, deux scores à deux bandes d’écart, une plage affectée dont la borne supérieure correspond à une build livrée en février, et aucune correction nommée. Quiconque effectue le triage de CVE-2026-75130 doit décider en fonction de ce que leurs agents peuvent atteindre, car le registre ne leur indique pas quelle version installer.