Cursor's agent can read a Slack channel, summarize a GitHub issue, or process a file in a repo you just cloned. In two vulnerabilities disclosed in mid-2025, researchers showed that content like that could also make the agent rewrite .cursor/mcp.json — the file that tells Cursor which MCP servers to trust and run — without the developer approving that specific change. Once the file pointed at a server the attacker controlled, Cursor ran it with the developer's own privileges. No malicious npm package, no compromised MCP registry entry — just an agent convinced to write a trust-boundary file that it would then honor itself.
This post walks through both bugs, the "write-then-trust" pattern they share, and what a local observability tool like Beam can and can't do about a config file that changes after you've already reviewed it once.
TL;DR
| Question | Answer |
|---|---|
| What are the two vulnerabilities? | CurXecute (CVE-2025-54135, CVSS 8.6) and MCPoison (CVE-2025-54136, CVSS 7.2) |
| Who disclosed them? | CurXecute: Aim Labs / AIM Security. MCPoison: Check Point Research. |
| Does this need user interaction? | Only the ordinary act of asking the agent to do a task (e.g. "summarize my Slack messages," or opening a shared repo) — not a click on a malicious link |
| What carries the injection? | CurXecute: a crafted message in a Slack channel, read by an already-approved Slack MCP server. MCPoison: a config-file swap in a shared Git repository after initial approval. |
| Which product is affected? | Cursor (Anysphere), versions 1.2.4 and below (MCPoison) / up to the pre-1.3.9 line (CurXecute) |
| Is it patched? | Yes, both fixed in Cursor 1.3, released July 29, 2025 |
| Does this affect Claude Code or Codex the same way? | Not directly reported — this is Cursor-specific tooling behavior, but the general "agent writes a config file it will later trust" pattern applies wherever an agent has write access to its own trust-boundary files |
| Would Beam's current scanner catch a silent rewrite as it happens? | No — Beam scans an MCP config on demand and can ingest hook events, but v1 has no standing filesystem watch on .cursor/mcp.json for unrequested writes |
The MCP config trust model Cursor relied on
MCP servers are how Cursor's agent gets extra tools — a Slack connector, a database client, a browser automation server. Cursor stores which servers to launch, and how, in .cursor/mcp.json for a project or ~/.cursor/mcp.json globally. The first time a new server entry shows up, Cursor asks the developer to approve it.
That single approval was doing more work than it should have. Two independent research teams found that once a server name was approved, Cursor's trust extended to whatever command and arguments later appeared under that name — and in one case, to a config file the agent itself had just written.
MCPoison (CVE-2025-54136): approve once, trust forever
Check Point Research found that Cursor bound trust to an MCP server's name, not its actual command or arguments. An attacker could commit a harmless-looking MCP entry to a shared repository — something as unremarkable as an echo call — wait for a collaborator to accept it once, then swap the underlying command for something else entirely, including a reverse shell. Because the name hadn't changed, Cursor re-ran the modified entry with no new prompt on the next project open. Check Point disclosed this to Cursor on July 16, 2025, and published it August 5, 2025.
CurXecute (CVE-2025-54135): the agent writes the file itself
Aim Labs' finding, which they named CurXecute, went a step further: the agent didn't need a human to touch the repository at all. In their proof of concept, a developer asked Cursor's agent to use its already-approved Slack MCP connection to summarize messages in a public channel. An attacker had planted a crafted message in that channel — an indirect prompt injection — instructing the agent to modify the global ~/.cursor/mcp.json and add a new server entry pointing at attacker-controlled code. Because Cursor auto-started newly written MCP server entries, the malicious server ran before the developer had any chance to reject the edit. Aim Labs disclosed this to Cursor on July 7, 2025, and published it August 1, 2025.
The common thread: in both cases, the file that decides what Cursor is allowed to run could be changed by something other than a deliberate, reviewed developer action — a collaborator's earlier approval in MCPoison's case, the agent's own write in CurXecute's case — and Cursor then trusted that changed file without asking again.
The write-then-trust attack path
Strip away the Cursor-specific detail and the pattern generalizes:
- An agent has read access to untrusted content — a web page, a Slack channel, a file in a cloned repo, a GitHub issue — as part of a task the developer actually asked for.
- That content carries instructions the agent wasn't supposed to follow (indirect prompt injection).
- The agent also has write access to the project or user directory.
- The injected instructions direct the agent to write or modify a config file that the agent's own runtime treats as a trust boundary — in this case, which MCP servers to load and run.
- The runtime reloads or re-trusts that file, sometimes automatically, and executes whatever it now points to with the developer's local privileges.
The attacker never needed code execution capability of their own. They needed the agent to write one file that the agent would then honor. That's a meaningfully different risk shape than a typical supply-chain compromise — there's no external package registry, no compromised MCP server binary to catch by scanning dependencies. The vulnerable artifact is created locally, by the tool the developer already trusts, in response to content the developer asked it to process.
This is the same class of concern our MCP server security review post raises about pinning and reviewing servers before you connect them — except CurXecute and MCPoison show that "before you connect" isn't a one-time gate if the config file itself can be rewritten afterward. It's also distinct from the tool-poisoning and rug-pull patterns covered in our practical guide to MCP security: those attacks hide instructions inside an already-connected server's tool descriptions, while CurXecute and MCPoison attack the layer above that — the file deciding which servers get connected at all.
What Cursor changed
Anysphere shipped a fix for both issues in Cursor 1.3, released July 29, 2025. The core change: any modification to an MCP configuration entry now requires explicit user re-approval, not just the first time a server name appears. Check Point's write-up notes the re-approval trigger is deliberately strict — "including something as small as adding a space" to a command — closing the specific gap MCPoison exploited, where trust was bound to a name rather than to the actual command and arguments behind it.
What to watch for, whichever agent you run
Cursor patched these specific bugs, but the underlying pattern — an agent writing a config file it will later trust — is worth building a habit around regardless of which coding agent you use:
- Keep MCP config files under version control.
.cursor/mcp.json,.claude/settings.json, and similar files should be tracked in git even in a personal repo, so an unrequested write shows up as a diff you can actually see instead of a silent change on disk. - Diff after any session that touched an MCP-connected tool. If an agent session read Slack messages, fetched a web page, or processed content from a repo you didn't write yourself, check
git statusandgit diffon your MCP config files before your next session, not after something goes wrong. - Treat an agent-proposed edit to a config file as a stop-and-read moment. A proposed change to
mcp.json,settings.json, or any file that controls what the agent is allowed to run next deserves the same scrutiny as a proposed shell command — arguably more, since its blast radius is "everything the agent does from now on." - Check the global config, not just the project one. CurXecute targeted
~/.cursor/mcp.json, outside the repository entirely. A review habit scoped only to the current project's files misses it. - Watch what an MCP server is actually pointed at, not just whether one exists. A config entry's command and arguments are the part that matters; a familiar-looking server name tells you nothing about what it currently runs.
Where Beam fits, and where it doesn't yet
Beam is a local-first observability tool for what AI coding agents do on your machine — it watches, flags, and lets you inspect evidence; per its own documentation it does not block or prevent actions in this version. Two of its actual, documented capabilities are relevant here:
- On-demand MCP config scanning.
bun run --cwd apps/sentinel-collector cli scan /absolute/path/to/mcp.json --mcp(or the equivalentbeam scan file.json --mcpCLI form) runs 11 heuristic patterns plus an MCP version-pin check against a config file you point it at — covering things like credential-delivery instructions, downloaded/encoded execution, and persistence targets. This is useful for reviewing a config before you trust it, but it only runs when you explicitly invoke it. - Hook-based event capture. A Claude Code
PreToolUse/PostToolUsehook can forward tool-use events to Beam's local collector, and Numbat-sourced events for other agents can be imported the same way. This gives you a record of what an agent did, after the fact, if the hook is installed and the agent in question emits through it.
Here's the honest gap: neither capability is a standing watch on .cursor/mcp.json for unrequested writes. Beam doesn't currently detect the moment an agent modifies that file outside a session you explicitly scanned — you'd need to re-run the scanner yourself, or notice the change some other way (like the git-diff habit above), before Beam's scan has anything new to look at. If Cursor emitted a capturable event for "agent wrote a file at this path" through a hook Beam ingests, that write would show up in Beam's activity log for you to review — but that depends on the agent surfacing the event, and reviewing a logged event after the fact is not the same as being warned before the write lands, let alone anything blocking it. This is the real distinction between a config scanned once and a config that changes later, and it's the gap this specific attack sits in.
Summary
CurXecute and MCPoison both broke the same assumption: that a config file an agent trusts and a config file a developer has actually reviewed are the same thing. One let an indirect prompt injection from a Slack message make the agent write that file itself; the other let a repository collaborator's earlier approval cover a later, unrelated swap. Both reached remote code execution without any external package compromise — just a local file, written by a tool the developer trusted, that the same tool then trusted back. Cursor 1.3 closes both specific paths by requiring re-approval on every config change. The broader habit worth keeping regardless of which agent you run: version-control your agent's trust-boundary config files, diff them after any session that processed untrusted content, and treat a proposed edit to one of them as seriously as a proposed shell command.
Sources:
- CurXecute — Cursor .cursor/mcp.json Injected-Server Auto-Exec RCE (CVE-2025-54135) — Agent Threat Rule catalog entry
- 'CurXecute' – RCE in Cursor via MCP Auto-Start — Cato Networks analysis
- Cursor IDE's MCP Vulnerability (MCPoison) — Check Point Research, original disclosure writeup
- Cursor AI Code Editor vulnerabilities CurXecute and MCPoison — FAQ — Tenable
- Cursor AI Code Editor Vulnerability Enables RCE via Malicious MCP File Swaps Post Approval — The Hacker News
Related on Beam: How to stop Cursor from running dangerous commands, Agentjacking: how a Sentry MCP integration hijacks coding agents — the same write-then-trust pattern arriving through a different channel, AI agent security incidents: a timeline, What is AI agent monitoring?
Version numbers, CVE details, and fix timelines above reflect public reporting as of this post's publication date; check Cursor's current changelog for the latest patch status. Beam's own capabilities are accurate to its README as of this writing and describe a local, v0.1 prototype — not a fleet-managed or enforcement product.