Rules / CFG095
CFG095 committed .cursor/sandbox.json weakens the agent's execution sandbox
Severity: error (sandbox disabled, network posture inverted, credential/system/root grant) · warn (unbounded allow pattern, other outside-workspace write grant, shared build cache)
OWASP: LLM03:2026 – Excessive Agency
What cfgaudit checks
Cursor 2.5 added .cursor/sandbox.json, the profile that bounds what agent-run commands may touch. cfgaudit reports a project file that widens it.
| Finding | Severity |
|---|---|
type: "insecure_none" — documented as "disables the sandbox entirely" |
error |
networkPolicy.default: "allow" — Cursor's documented default is deny |
error |
additionalReadwritePaths naming a credential directory, the home directory or / |
error |
additionalReadwritePaths naming a system directory (/etc, /usr, /bin, …) |
error |
additionalReadonlyPaths naming a credential directory, the home directory or / |
error |
networkPolicy.allow containing "*", "0.0.0.0/0", "::/0" |
warn |
any other additionalReadwritePaths grant outside the workspace |
warn |
enableSharedBuildCache: true |
warn |
This is the sandbox-weakening family CFG022 covers for Claude Code, CFG061 for Gemini CLI and CFG064 for Codex, reached through Cursor's file. type: "insecure_none" is the direct analogue of Codex's sandbox_mode: danger-full-access.
Why a committed file is the finding
Cursor reads two sandbox files and merges them "with per-repo settings taking priority":
~/.cursor/sandbox.json # all workspaces
<workspace>/.cursor/sandbox.json # single workspace, per-repo
That sentence is the summary. The same reference's "How policies merge" section is field by field (#649):
| Field | Merge |
|---|---|
additionalReadwritePaths, additionalReadonlyPaths |
unioned across sources |
networkPolicy.allow |
unioned (unless a team-admin allowlist replaces the union) |
networkPolicy.deny |
always unioned |
networkPolicy.default |
"deny" wins over "allow" |
disableTmpWrite, networkPolicyStrict |
true wins |
readBoundary |
per-repo replaces per-user |
additionalReadPaths |
per-repo replaces per-user, then the team-admin list is added |
So a committed file adds paths and allowed hosts to every teammate's sandbox, flips networkPolicy.default for a teammate who has no file of their own (a teammate who wrote "deny" keeps it), and decides readBoundary and the Read Allowlist outright. type is not in the list, so the summary's per-repo priority applies to it.
The read boundary (Cursor 3.23+)
readBoundary is "system" by default; "workspace" asks before the agent reads outside the workspace. Because the repository's value replaces the user's, a committed "system" undoes a teammate's "workspace" (warn), and a credential directory, the home directory or the filesystem root in additionalReadPaths is read without asking (error).
Read-only grants are still findings
additionalReadonlyPaths cannot be used to write outside the workspace, so system directories there are not reported — reading /usr is unremarkable. A credential directory is different: read access is all an exfiltration path needs, so ~/.ssh or ~/.aws in the read-only list is an error just as it is in the read-write list.
What is deliberately not flagged
type: "workspace_readonly"— stricter than the default.disableTmpWrite: true— the reference states it "removes default write access to/tmpand system temp directories", so setting it makes the sandbox more restrictive. The issue that requested this rule listed it as a footgun to flag; the documentation says the opposite, and reporting hardening as a weakness would be a false positive.- A grant that stays inside the workspace. That is the sandbox's own scope. A relative path resolves against the workspace and is treated as inside, so a repo widening its own build directory is silent.
networkPolicy.denyentries. They only tighten, and Cursor documents that "deny always beats allow".
enableSharedBuildCache and why it is only warn
Cursor documents it as redirecting build-tool caches "to a shared tmpdir so sandboxed and unsandboxed commands share the same caches". That is a writable channel across the sandbox boundary by construction: what a sandboxed agent command writes into the cache is what a later unsandboxed command reads.
It is warn rather than error because the documentation describes it as a build-performance feature and makes no claim either way about the isolation consequence. The finding states the mechanism and lets a reviewer judge; asserting an exploit would go beyond what the reference supports.
Fix
{
"type": "workspace_readwrite",
"networkPolicy": {
"default": "deny",
"allow": ["registry.npmjs.org", "*.githubusercontent.com"]
},
"additionalReadwritePaths": ["./build-cache"]
}
Scope
Project scope only. A user's own ~/.cursor/sandbox.json is self-intentional — the same reason CFG093 stays off the per-user permissions file.
References
Documentation for cfgaudit 1.18.1. Source of this page · Rule implementation