CurXecute: when a Slack message rewrites your editor’s config and runs code | by Hideaki Takahashi | Jul, 2026 | MediumSitemapOpen in appSign up<br>Sign in
Medium Logo
Get app<br>Write
Search
Sign up<br>Sign in
CurXecute: when a Slack message rewrites your editor’s config and runs code
Hideaki Takahashi
5 min read·<br>Just now
Listen
Share
A single crafted Slack message turned Cursor’s MCP integration into remote code execution, and how running the agent inside h5i env would have kept the damage inside a sealed worktree.<br>What happened<br>Press enter or click to view image in full size
In July 2025, researchers at Aim Labs (working with the broader Cursor security community) disclosed CVE-2025–54135, nicknamed “CurXecute,” a remote-code-execution flaw in the Cursor AI code editor. The details were published by Cato Networks and summarized by Tenable and The Hacker News. It was reported through coordinated disclosure on 7 July 2025 and fixed in Cursor version 1.3, released on 29 July 2025.<br>The attack chain starts with a legitimate feature. Cursor can connect to Model Context Protocol (MCP) servers that pull in external context: in the demonstrated case, a Slack MCP server that reads messages from a workspace. An attacker who can post into a channel the victim’s agent reads sends a crafted Slack message. When Cursor processes that untrusted message, it is steered into writing or modifying the global MCP configuration file at ~/.cursor/mcp.json using content derived from the attacker's message.<br>The critical detail is the timing. Cursor executed the newly-added MCP command immediately, before the user had any chance to review or reject the suggested edit. A suggested configuration change that a human would normally inspect was already running by the time it appeared. Because Cursor runs with the developer’s own privileges, a single externally-hosted prompt injection became full remote code execution on the developer’s machine.<br>Check Point Research separately documented a related issue, CVE-2025–54136 (“MCPoison”), in which the contents of an already-approved MCP command could be swapped out later, so a benign approval turned malicious after the fact.<br>Root cause<br>Untrusted external data flowed, unmediated, into a privileged configuration file that auto-executes commands.<br>Three architectural choices combine to make this exploitable:<br>The trust boundary was in the wrong place. Text from a Slack message, fully attacker-controlled, was treated as trustworthy enough to drive edits to an execution-defining config file.<br>Write and execute were fused with no gate between them. Cursor added an MCP command and ran it in the same motion, so the human review step (rejecting a suggested edit) happened after execution rather than before it.<br>The agent ran at full host privilege. Whatever the injected command did, it did as the developer: their files, their credentials, their network.<br>The prompt injection itself is a model-layer problem. But the blast radius, RCE at developer privilege, is an architecture problem: no confirmation before execution, and no privilege separation between “the editor” and “arbitrary commands the editor was talked into running.”<br>Impact<br>Remote code execution on the developer’s machine, at the developer’s privilege level, triggered by a message the developer never chose to trust. From there an attacker could read source code and secrets (~/.ssh, ~/.aws, .env files), tamper with the repository, or pivot onto internal networks. The fix in Cursor 1.3 makes any change to an MCP configuration require explicit user approval before it takes effect, restoring the missing gate.<br>How h5i env changes the outcome<br>Press enter or click to view image in full size
h5i env does not stop Cursor from rewriting ~/.cursor/mcp.json, and it does not detect the malicious Slack message. What it changes is whose privilege the auto-executed command runs at. If the agent workflow, or at least the commands it triggers, runs inside the box, the injected command executes at the box's privilege, not the host's.<br>Run untrusted-MCP work in a confined worktree:<br>h5i env create mcp-triage --isolation supervised # fails closed if the host can't enforce it<br>h5i env shell mcp-triage -- claude --dangerously-skip-permissions ""<br>h5i env diff mcp-triage<br>h5i env propose mcp-triage<br>h5i env apply mcp-triageA policy that neutralizes the RCE’s value:<br>[profile.mcp-triage]<br>isolation = "supervised"<br>[profile.mcp-triage.fs]<br>write = ["$WORK"] # Landlock: only the worktree is writable<br>deny = ["~/.ssh", "~/.aws"] # preflight lint against granting credential dirs<br>[profile.mcp-triage.net]<br>mode = "deny" # empty netns: no exfiltration, no C2, no pivot<br>[profile.mcp-triage.env]<br>pass = ["PATH", "HOME", "LANG"] # no cloud creds inheritedTrace it against the attack. The Slack message still steers a config rewrite, and the command still fires without confirmation. But now:<br>Filesystem (Landlock allowlist). write = ["$WORK"] means the command can only write inside the worktree. It...