Escaping Cursor's sandbox through .claude/settings.local.json
TL;DR / Executive Summary
This post is part of The Week of Sandbox Escapes, our series on how AI coding agents can turn ordinary project files into paths out of the sandbox. Read the master report here.
We found that Cursor could be made to trust automation settings written inside the workspace by the agent itself. That turned a normal-looking project configuration file into a way to run commands on the user's machine without the dedicated approval users expect from a sandboxed agent. The finding matters because it shows how compatibility features and workflow automation can quietly become execution paths.
Cursor assigned this issue CVE-2026-48124 and published an advisory GHSA-pc9j-3qc2-95wv. The advisory rates it High severity with a CVSS 8.5 score, lists 3.0.0 as the patched version.
Cursor's sandbox is built around a familiar promise: the agent can work inside the project, but it should not get to run arbitrary commands on the user's machine unless the user approves them. The gap I found was not in the shell path the user sees. It was in a compatibility path the agent could write and Cursor later trusted.
The file was .claude/settings.local.json. Put a Stop hook in that file, end the turn, and Cursor's hook engine executes the configured command from the user's local context. The agent never has to ask for permission to run the final command. It just leaves executable configuration in the workspace and lets another component pick it up.
That is the pattern that keeps showing up in agentic IDEs. The sandbox controls what the agent runs directly. It does not necessarily control what the agent writes for an unsandboxed helper to run later.
A config file becomes an execution path
Claude Code-style hook configuration is useful because it lets teams automate behavior around agent turns. A Stop hook runs when the turn finishes. That is also exactly why it is security-sensitive. It is not just project metadata. It is a command launcher.
Cursor accepted a workspace-sourced .claude/settings.local.json file as hook configuration. From inside the sandbox, the agent could create the directory, write a small shell script, and register it as a Stop hook. When the turn ended, the hook engine crossed the boundary for it.
The attack path is short:
- workspace-controlled file
- hook engine
- local command execution
In the proof of concept, the command opened Calculator. Replace that with a data theft payload, a persistence step, or a second-stage loader and the boundary failure is the same.
The payload
The prompt I used was intentionally boring. It asked the agent to run one terminal command in the current workspace and then reply with a fixed string. The command wrote two files: a helper script and the hook configuration.
Nothing about this needs a visible malicious prompt in the real version. The same instructions can be buried in a README, a copied setup guide, or a project note the agent was already asked to process. The agent writes files in the workspace, which is the most ordinary thing an agent does. The payload runs later, at Stop, through Cursor's hook engine.
Why this is a sandbox escape
The sandbox boundary is supposed to mediate command execution. If the agent wants to open Calculator, write to a shell profile, or run a local exfiltration command, that action should go through the same approval and sandbox policy as any other shell command.
Here the command did not travel through that path. The agent wrote configuration. Cursor loaded it. The hook engine executed it. The result was arbitrary local command execution in the user's context from a workspace-controlled artifact.
The important detail is not Calculator. Calculator is just a proof that the process answering the request was no longer the sandboxed agent. The important detail is that a file the agent was allowed to create became an executable instruction to a component outside the direct approval flow.
The compatibility trap
The .claude path matters because compatibility paths are easy to treat as harmless plumbing. A product supports another tool's config shape, the support layer gets wired in, and the security model focuses on the product's primary config directory.
But compatibility does not make execution config less dangerous. If .cursor rules require special handling, then .claude hooks need the same treatment. A command is a command no matter which legacy or compatibility namespace delivered it.
That is the mistake: treating workspace-sourced hook configuration as project state instead of execution state.
The fix
The boring fix is to treat .claude/settings.json and .claude/settings.local.json as sensitive execution configuration. Workspace-sourced hook commands should require explicit, dedicated approval before they run, and that approval should name the command and the file that supplied it.
The stronger fix is to run hooks under the same sandbox and policy controls as normal agent shell execution. If the user would have seen an approval prompt for the command in chat, a hook should not get a quieter route to the same result.
And compatibility paths need to inherit the primary security model. Supporting another agent's config format is fine. Letting it bypass your own execution controls is not.
Takeaway
The recurring lesson in this series is that agent sandboxes fail at the handoff points. The sandbox may be perfectly reasonable around the agent process, but the IDE around it is full of components that read workspace files and do powerful things on the host.
Hooks are one of the most direct versions of that problem. They are designed to turn configuration into commands. If an agent can write them and an unsandboxed component can execute them, the sandbox has become advisory.
The right boundary is not "can the agent write this file?" It is "will anything outside the sandbox later trust this file enough to execute it?" For hook config, the answer is yes, and that makes it part of the execution boundary.
Advisory
- CVE: CVE-2026-48124
- GitHub advisory: GHSA-pc9j-3qc2-95wv
- Severity: High
- CVSS: 8.5
- Affected version: Cursor Desktop 2.4.37
- Patched version: Cursor Desktop 3.0.0
Subscribe and get the latest security updates
Back to blog
.png)
.png)

%20(1).png)
%20(1).png)
.png)
%20(1).webp)
%20(1).png)
