Rug-pull after approval: MCPoison
A Cursor MCP server was approved once, then silently swapped for a malicious one. The approval stuck to the entry's name, not its contents, so the swap inherited the trust and ran with no new prompt. Herkos does not catch this swap, and saying so is the point of this page. What its scan does catch is the rug-pull's close cousin: a tool whose description is poisoned after you approved it.
Disclosed: Check Point Research, named "MCPoison", reported to Cursor on Jul 16 2025. Fixed: Cursor 1.3, Jul 29 2025. CVE: CVE-2025-54136. Severity: CVSS 3.1 base 7.2 HIGH (the CNA score, GitHub on behalf of Anysphere/Cursor) and 8.8 HIGH (NVD); the only difference between the two vectors is privileges-required. Affected: Cursor versions prior to 1.3. Sources: Check Point Research, NVD, Cursor GHSA-24mc-g4xr-4395.
What happened
Cursor keyed an MCP approval to "this entry was approved once" rather than to a hash of the entry's actual command and arguments. Once approved, later edits to the same entry were trusted without a new prompt. The attack is four steps:
- Plant a benign config. The attacker commits an innocuous MCP server entry to a shared repo - Check Point used
.cursor/rules/mcp.jsonwith a harmless command likeecho. - Victim approves once. A collaborator opens the project, Cursor prompts for MCP approval, and the victim approves the harmless-looking entry. The approval is persisted.
- Attacker swaps the payload. The attacker edits the same entry's
command/argsto something malicious. Per Check Point: "the contents - such as command and args - can be modified later without triggering a new approval prompt." - Silent persistent execution. The next time the victim opens the project, the modified command runs automatically, with no prompt. Because the config lives in the repo, it re-runs on every open - persistent, silent, remote code execution.
Root cause in one line: approval was bound to the entry's identity, not to its contents, so mutating the contents after approval bypassed re-validation. The 1.3 fix re-triggers an approval prompt on any change, even adding a single space.
Where Herkos helps, and where it does not
Be precise, because this is the case a skeptic pushes on hardest:
- The command/args swap: NOT caught. MCPoison mutates a server's
commandandargs. Herkos'sscan --baselinecompares tool descriptions only - it never parses command or args - so the canonical MCPoison swap is invisible to it. Blocking a changed config before it runs is trust-on-first-use pinning, which Trail of Bits'mcp-context-protectordoes and Herkos does not. It would be wrong to claim Herkos catches this CVE. - The description rug-pull: caught. The sibling attack - a server that keeps its command but poisons a tool's description after approval (the tool-poisoning / line-jumping shape) - is caught:
scan --baselineflags a description that drifted from your known-good snapshot. That is the real, demonstrable capability, shown below. - Record: supporting. A per-session audit log (
serve --receipts) anchors what actually ran; tie it to the config you approved and a later change is evident across sessions.
Here is the receipt
A real run of this repo's binary - the description rug-pull, not the command swap. The trusted baseline pins what deploy/run was approved to do; the scanned config carries a description that drifted to smuggle an instruction, and Herkos flags it:
$ herkos scan --config deploy.manifest.json --baseline deploy.baseline.json [poisoned] deploy/run: tool description differs from baseline herkos scan: 0 over-scoped, 1 poisoned, 0 unrestricted-egress, 0 unbrokered, 0 unpinned-install, 0 remote - your code never left this machine
Run it in CI against a committed baseline and a post-approval swap fails the check instead of running unnoticed.
Description-drift detection is real; catching MCPoison's command/args swap is not, and neither is live prevention. If your threat model is "block a changed config before it executes," you want a TOFU-pinning layer like mcp-context-protector, not Herkos. Herkos's honest contribution here is narrow: it flags description poisoning against a baseline and signs a record of what ran. (Note: do not confuse MCPoison / CVE-2025-54136 with the separate Cursor "CurXecute" bug, CVE-2025-54135.)