Abstract technical illustration on a deep slate field: a narrow documentation-server column at left passes small rectangular cards along a lit channel toward a single agent node at right, which holds a ring of small key-shaped objects. One of the cards is outlined in amber and carries a faint key silhouette that is mirrored in the agent's ring. Behind the column sits a loose grid of library entries, one of them shaded darker than the rest. Thin teal rules divide the channel into delivery segments. No people, no logos, no lettering of any kind. The OrcaRouter logo is composited in the bottom-right corner.
AI Safety Incidents

CVE-2026-75130: Context7's MCP documentation server scores 9.0, and the record names no fixed version

Author

Alistair Wren

Date Published

Latest models · 20View all models →
Benchmarks: Artificial Analysis · updated daily
Back to all posts

On 18 August 2026 VulnCheck published CVE-2026-75130 against Context7, the library-documentation server Upstash runs for the Model Context Protocol and that coding agents query for version-specific docs. The flaw sits in the feature Upstash calls Custom AI Instructions: a library owner attaches guidance to a documentation entry, Context7 serves that guidance into the context window of every agent that looks the library up, and nothing on that path sanitises it. Noma Security, whose senior AI vulnerability researcher Eli Ainhorn is credited as the finder, demonstrated that a poisoned entry can make a connected agent read .env files in the project root, send their contents to a GitHub repository the attacker controls as an issue, and delete local folders under a “cleanup” pretext — all from a routine documentation request. No victim is recorded. The rest of the documented agent incidents, each with its own severity, confidence grade and disputed flag, sit in the AI incident archive, where this record's neighbouring entries can be read next to it.

Context7's server is small, and that is the part worth understanding first. Noma's writeup notes that it exposes two tools, resolve-library-id and query-docs, and that it cannot execute code, write files or reach the network on its own. Every documented impact is carried out by the agent on the other end, which does hold filesystem, shell and network access on the developer's machine. The npm registry shows how large the installed base is: @upstash/context7-mcp was downloaded 4,064,176 times in the thirty days from 22 July to 20 August 2026, the window around publication.

The mechanism: one poisoned library, every agent that queries it

Noma's demonstration, described in its ContextCrush writeup of 5 March 2026, ran in three steps that the agent performs rather than the server. It registered a library in Context7's registry with poisoned rules attached. Instructions in those rules directed the agent to search for and read every .env file in the project root; further instructions directed it to post the contents to an attacker-controlled GitHub repository as an issue; a final set told it to delete local folders and files for “cleanup.” The request that pulls all of this into context is an ordinary one — asking a coding assistant for help with a library.

The reason this is a supply-chain problem rather than ordinary prompt injection is where the payload lives. The attacker never reaches the victim's machine and never has to plant text in a document the user opens. The poisoned instructions sit on Context7's own registry, are hosted and served by Context7's own infrastructure, and arrive through the same trusted channel as the legitimate documentation, indistinguishable from it. Noma notes that Context7's trust score, which rates libraries on the GitHub history behind them, does not defend against this, because a long-lived account can be bought, hijacked or manufactured. The company's own summary of the structural point is blunt: “The attack surface isn't what the MCP server can do. It's in what it can make the AI agent do.”

Two scores for one bug

The advisory carries CVSS 3.1 9.0 (critical) and CVSS 4.0 6.4 (medium). Both vectors were supplied by VulnCheck as the assigning CNA, and NVD carries both unchanged, attributing each to VulnCheck. The split is not a mistake; it is the two frameworks counting the same damage against different machines. CVSS 3.1 flags Scope as Changed — the injection crosses from the server to the developer's machine and beyond — and so books the full high confidentiality, integrity and availability impact of the agent's capabilities at full weight. CVSS 4.0 replaces Scope with separate metrics for the vulnerable system and the subsequent one: it records no confidentiality, integrity or availability impact for Context7 itself (VC:N/VI:N/VA:N) and high impact on the systems downstream (SC:H/SI:H/SA:H), which its formula weights less heavily. The server is the courier, not the victim.

The split propagates into the databases. GitHub's advisory, GHSA-97r6-3rgm-v39r, was published at 18:32 UTC on 18 August, half an hour after the CVE, and its summary severity reads medium even though the CVSS 3.1 vector in the same record scores 9.0. ENISA's EU Vulnerability Database mirrors the entry as EUVD-2026-61099 and stores a base score of 6.4 under version 4.0 only. The archive record this article follows grades the incident high — which is neither of the two published scores — and it is the archive's grade, not a measurement of its own.

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.'

A CVE published in August for a March disclosure

The CVE identifier was reserved on 17 August 2026 and published at 18:02 UTC on 18 August, which is the date the record carries. The CNA container also carries a second date that does not appear on the aggregator pages: datePublic, 5 March 2026 — five and a half months before the identifier existed, and the same day Noma published ContextCrush. The advisory's only technical reference is that March writeup, which VulnCheck tags for both technical description and exploit.

Noma's disclosure timeline explains the gap. It reports the flaw to Upstash on 18 February 2026 with a full report and proof of concept, records Upstash accepting the findings and beginning remediation on 19 February, says a fix was “deployed to production with rule sanitization and guardrails” on 23 February, and dates public disclosure and final verification by Noma to 5 March. By Noma's account the February bug was resolved in days.

The npm registry dates line up with that timeline in a way that leaves the affected range looking odd. @upstash/context7-mcp 2.1.2 was published on 23 February 2026 at 10:06 UTC, the day Noma says the fix reached production; its changelog line reads “Remove unnecessary warning and update tool descriptions.” 2.1.3 followed on 4 March 2026, the day before Noma's writeup, with notes about rejecting GET requests on MCP endpoints and adding a source field to search results. Neither release note mentions sanitisation, guardrails or the injection. The CNA's affected range ends at 2.1.2, which makes 2.1.3 the first version outside it.

Three readings fit those dates, and neither VulnCheck nor Noma states which is correct. The first, argued by Digital Applied in its 18 August piece and repeated by AI Security Wire on 22 August, is that the fix regressed: the build that carried February's patch sits inside August's affected range. The second is that the range is simply anchored to the build the researcher tested, and that 2.1.3, shipped the day before disclosure, is the real boundary — an inference several aggregators make mechanically, including Feedly, which lists “update to version 2.1.3 or later” as mitigation. The third is that the February fix was applied where the rules are served rather than in the client package, in which case an npm version range does not describe the fix at all. A silent security fix is common enough that the absence of a matching changelog entry settles nothing either way.

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.'

What is established, and what is not

• Established by the primary record. The CVE identifier, its 18 August publication, VulnCheck as CNA, the CWE-1427 classification for improper neutralisation of input used for LLM prompting, the credit to Eli Ainhorn of Noma Security, and an affected range of Context7 through 2.1.2.

• Established by Noma's research. The injection path through Custom AI Instructions, the three-step proof of concept, the observation that the server exposes only resolve-library-id and query-docs, and the statement that no evidence of exploitation in the wild was observed for the February bug.

• Established by the registry. The 2.1.2 publication date of 23 February 2026, the 2.1.3 publication date of 4 March 2026, and a package line that has since run past 4.0 to 4.4.4 on 19 October 2026.

• Not established: whether current builds are affected. No source says the 4.x line is vulnerable, and no source says it is clear. The CVE record, the VulnCheck advisory and the GitHub advisory all name no fixed version, and the GitHub advisory's list of vulnerable version ranges is empty.

• Not established: any victim or in-the-wild use. The archive records real harm as false. CISA's enrichment of the record on 19 August scored Exploitation as “none”, Automatable as “no” and Technical Impact as “total”; the flaw is not in the KEV catalogue; ENISA's mirror records an EPSS of 0.49 percent. Noma's research is a demonstration, not an incident report.

• Not established: the regression reading itself. It rests on a date coincidence between a fix timeline and an npm publication, and no primary source asserts that the same code path failed twice.

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: restatement, and silence where it matters

The documents that agree with the record are largely derived from it. VulnCheck's advisory restates the CVE text and adds the weakness classification and the researcher credit. The GitHub advisory is an alias of the same submission, published the same evening, with no version ranges and no independent review. ENISA's entry is a mirror. Digital Applied, one of the two sources the archive cites, published its analysis on 18 August and updated it on 22 August with fresh registry pulls; AI Security Wire published a second write-up on 22 August. Both restate the advisory and forward the regression inference, and neither claims to have verified it independently.

We found no newsroom coverage of the CVE on 29 October 2026 — no BleepingComputer, The Register or SecurityWeek item — and the results were CVE aggregator pages rather than reporting. That absence matters for how the record should be read: the archive grades it A, well documented with primary sources that agree, and the primary sources do agree, but agreement here is between a CNA record and the research it cites, not between two independent measurements. Several aggregator pages add claims their sources do not support; Feedly's entry, for instance, states that a patch is available and names 2.1.3, which no advisory does, while VulDB's page returned a bot check instead of content and could not be read at all.

What changed, and what did not

For the February bug, Upstash moved in days: accepted on 19 February, fixed on 23 February, by Noma's account. For the August record the only supplier statement the CVE references is a LinkedIn post from Upstash, tagged there as a vendor advisory, whose content we could not read without a session. No GitHub security advisory scoped to the repository carries a fixed version, and NVD's entry sits at status Deferred with no CPE configurations and a last modification of 22 October 2026, so NVD's own analysis is not in the record.

The package itself kept shipping. Between 20 April 2025 and 23 October 2026 the upstash/context7 repository published 163 releases, and none of their notes mentions this CVE or describes sanitising the custom instructions that carry the injection. That is a record of what the maintainers chose to write down, not proof that nothing was fixed.

What the record leaves an operator is exposure management rather than a patch line. Noma's recommendations centre on reviewing MCP integrations and inspecting what passes between agent and server at runtime; OpenCVE's suggested actions are to upgrade, to disable or restrict the Custom AI Instructions feature, and to add input validation to the server. The operational version of all of that is the same three moves: pin the MCP server version instead of floating on latest, keep production credentials out of plaintext environment files the agent can read, and treat tool responses as untrusted input rather than as documentation the agent may follow.

Ten weeks after publication the public record still ends where it did on 18 August: an identifier, two scores two bands apart, an affected range whose upper bound is a build that shipped in February, and no named fix. Whoever triages CVE-2026-75130 has to decide on what their agents can reach, because the record does not tell them what version to install.