Labs

No PR is Safe from Captain Hooks: Remote Code Execution on Cursor’s BugBot

Stiv Kupchik
Lumia Security LabsStiv Kupchik

August 26, 2026 | 6 min read

Cursor PR reviews can execute attacker-controlled project hooks from untrusted forked pull requests.

Cursor’s BugBot mishandles Pull Request (PR) reviews from forked repositories. A malicious actor can include a .cursor/hooks.json file that Cursor automatically loads during a PR review. This can allow an attacker who submits a PR from a fork to execute commands on a maintainer’s machine when that maintainer reviews the PR using the built-in Cursor workflow.

Introduction

Like most of us, I also use LLMs daily in my work, both for research and for development here at Lumia. My reliance on AI and agentic workflows have progressed over time as well, and recently I started using LLMs for code review as well. If my teammates use AI to review my PRs, I figured I could do the review loop myself before they get to it. 

This led me to look deeper into Cursor’s review process, where I found that content from an untrusted PR can cross an important trust boundary: attacker-controlled files under .cursor are checked out locally and then treated as trusted project configuration. The issue is not simply that Cursor reads attacker-controlled code during review. It is that attacker-controlled repository configuration can become executable configuration on the reviewer’s machine automatically. 

This leads to arbitrary command execution in the form of Cursor hooks injection, and can provide attackers with an entry point into any organization that maintains a public repository, or as a form of lateral movement inside an organization’s private repos.

First, Let’s Review the Process

Before we dive into the attack itself, it’s best to review (haha, get it?...)  how Cursor handles code reviews. To trigger a code review, we can use the /review command in the chat and give it a link to the PR on GitHub, or just the PR number. It uses the gh CLI to get the PR’s metadata and then review it. 

There are two modes for review - BugBot and Security Review. Both are vulnerable to the attack.

Fig 1: Cursor PR review process.

Once you select the mode you want for the review, Cursor loads the relevant skill for it, then it:

  1. Reads the PR metadata using gh.
  2. Checks out the remote branch locally using git CLI.
  3. Spawns a new agent to do the actual review.
Fig 2: The Review flow

Steps 2 and 3 make the attack possible; checking out the remote branch introduces new files locally, which are attacker controlled, and the new agent is then influenced by them.

.cursor, Agents, and Everything In Between

Even if we checkout the branch and get attacker-controlled content, it’s still just files no? If there’s any hidden prompt injection, direct or indirect, Cursor should be able to detect and alert on it, instead of acting.

But what if it was something that was meant for Cursor to load automatically, and isn’t even loading to the LLM? This is where the trust boundary breaks. The malicious content does not need to convince the model to execute anything; Cursor itself interprets the attacker-controlled .cursor configuration as trusted project configuration.

Cursor, like other AI coding assistants, allows users to customize behavior using special configuration files located in the .cursor folder. These files can define skills, rules, and project-specific instructions. Crucially, Cursor treats this folder as a trusted source, equivalent to direct user configurations.

The folder can contain skills, rules and specific instructions for Cursor to handle at the project level, and is treated as trusted, equal to user instructions.

The .cursor folder can also include hooks via a hooks.json file. Hooks are designed to execute commands during specific events, like starting a new conversation, sending a prompt or invoking a tool. They’re typically used for logging, environment set-up or governance. 

However, if an attacker can add their own command hooks, they basically achieve arbitrary command execution, which also allows them to retrieve and execute remote payloads as well (remember, hooks are trusted!)

The new subagent spawn for the review ensures the hooks are immediately loaded, and achieve direct execution. When Cursor spawns the review subagent, it loads the newly checked-out project configuration. At that point, the attacker-controlled hook has crossed from untrusted PR content into trusted executable configuration, resulting in command execution.

Fig 3: Arbitrary Command Execution following PR review

The Bane of Open Source

So Cursor loads files from PRs, what’s the big deal? You still need to have access to the repo, which means you already have a semblance of trust on it so there’s almost no escalation of permissions, right?

That might be true for closed repositories, but what if you’re maintaining a public repository?

Anyone can fork a public repository, add a malicious hooks file and submit a PR back to the original repo. If the original maintainer uses Cursor to triage or review that PR, the IDE automatically checks out the malicious branch, triggering the hooks and achieving remote code execution.

Once inside the maintainer’s machine, the attacker no longer needs the PR. They can close it, and potentially even modify the project and source code to introduce a backdoor permanently (like the pitfall attack we discovered previously), without needing to go through another PR again.

For solo developers this is a supply chain issue, for enterprise it could even be the entry point to the organization or a form of lateral movement.

Mitigations

The solution to this attack is very straightforward. Don’t check out remote branches for PR review. 

git diff exists for a reason, and reviewing the diff without checking out the branch is a very standard practice.

In fact, the reason we singled out Cursor in this blog and haven’t mentioned any other AI Coding Assistant, is precisely because they’re using git diff correctly for review and flag the PR as malicious without executing any hook whatsoever.

Fig 4: Claude Code correctly flags a similar PR as malicious

Responsible Disclosure

We reported this vulnerability to Cursor via HackerOne. 

Unfortunately, the report was closed as "informational" and "out-of-scope." The triager appeared to misunderstand the attack vector, incorrectly assuming it required the victim to manually clone the repository. 

Despite our efforts to clarify the impact, the status remains unchanged.

Disclosure Timeline

16/07/2026 - Opened disclosure via HackerOne

29/07/2026 - Disclosure triaged as out of scope

29/07/2026 - Commented to dispute triage verdict

02/08/2026 - Reached out again to HackerOne

Frequently Asked Questions

No PR is Safe from Captain Hooks: Remote Code Execution on Cursor’s BugBot

Stiv Kupchik
Lumia Security LabsStiv Kupchik

August 26, 2026 | 6 min read

The vulnerability allows attacker-controlled project hooks from a forked pull request to be loaded during Cursor’s PR review workflow. A malicious .cursor/hooks.json file can cause commands to execute on the maintainer’s machine when the PR is reviewed.

Cursor checks out the pull request branch locally before spawning a review agent. If the branch contains malicious Cursor project configuration, including executable hooks, that configuration can be treated as trusted and loaded automatically.

.cursor/hooks.json lets projects define commands that run during Cursor events such as starting conversations or invoking tools. If an untrusted pull request can introduce this file, those hooks may execute attacker-controlled commands on the reviewer’s system.

According to Lumia Security’s research, both Cursor’s BugBot and Security Review workflows are affected because both can check out the remote pull request branch and then launch a review agent that loads the project configuration.

Developers should avoid checking out untrusted remote branches solely to review a pull request. Reviewing the PR through git diff or another method that does not load attacker-controlled project configuration can prevent malicious hooks from executing.

Blocking AI apps is not an option anymore. Adopt AI. Safely. Reach out today to learn more.

We use cookies to enhance your browsing experience, serve personalised ads or content, and analyse our traffic. By clicking "Accept", you consent to our use of cookies.