Cursor's Agent mode runs real shell commands with your user account's permissions — the same account that can rm -rf a directory, force-push over a branch, or curl a script straight into bash. Cursor used to ship a command denylist for exactly this. It doesn't anymore: the company deprecated it in release 1.3 after security researchers showed the blocklist could be bypassed with nothing more exotic than a quoted echo. This guide covers what actually stands between Cursor's agent and a destructive command today — Run Modes, the terminal allowlist, .cursor/rules, and sandboxing — plus where a local monitor like Beam fits around those controls.
TL;DR
| Question | Answer |
|---|---|
| Does Cursor still have a "Command Denylist" setting? | No — deprecated in Cursor 1.3. Blocklist matching was proven bypassable (base64, subshells, quote-escaping like "e"cho). |
| What's the current safety mechanism? | Run Mode choice (Auto-review recommended) + terminalAllowlist in .cursor/permissions.json + optional sandboxing. |
| What happened to YOLO mode? | Renamed Auto-run, and superseded by three Run Modes: Allowlist, Auto-review, Run Everything. Run Everything is today's YOLO. |
Can .cursor/rules block a command? | No — Cursor's own docs describe rules as context for the agent, not an execution gate. |
| Is there an OS-level sandbox? | Yes, optional, via .cursor/sandbox.json — but an explicit insecure_none type can turn it off. |
| Does Beam block anything in Cursor? | No. Beam observes and flags locally per apps/sentinel-collector/README.md; it does not intercept commands, and Cursor-specific hook capture isn't documented there. |
Why the old denylist didn't work
Cursor originally let you list unsafe commands in Agent settings; if the agent tried to run one, it would pause and ask instead of auto-running it. Backslash Security's research demonstrated four ways around that list: base64-encoded commands that decode to the blocked string at execution time, subshell wrapping, blocked commands buried inside a shell script, and — the one that made the feature "mathematically undefendable" — quote escaping, where "e"cho executes identically to echo but never matches a literal string in the denylist. Cursor deprecated the denylist in release 1.3 as a direct result and pointed users toward an allowlist model instead, which inverts the problem: instead of enumerating infinite dangerous variants, you enumerate the finite set of commands you actually trust.
This is the same lesson Beam's own scanner is built around — Beam's skill scanner checks known dangerous shapes heuristically and states plainly that it isn't semantic analysis. Pattern-matching against arbitrary shell text has the same blind spots whether it's a denylist or a heuristic scan; neither is a proof of safety.
Cursor's current Run Modes
Cursor documents three Run Modes for Agent mode (cursor.com/docs/agent/security/run-modes):
Allowlist
Only pre-approved actions run without a prompt. Cursor calls this the right choice for "deterministic behavior with a small set of trusted repeat actions" — a CI-style workflow where the command surface is narrow and known ahead of time.
Auto-review (recommended default, Cursor 3.6+)
For each shell, MCP, or Fetch call, Cursor checks the allowlist first, runs the command in its sandbox when the command is sandboxable, and routes anything left over to an LLM classifier before it either runs or surfaces a human approval prompt. This is the closest thing to a modern "denylist" — except the block signal is a natural-language block_instructions hint that steers the classifier's judgment, not a hard rule.
Run Everything
Every tool call executes immediately: no allowlist check, no sandbox, no classifier, no prompt. This is what practitioners still call YOLO mode, because functionally it is — Cursor renamed the feature to Auto-run and then folded it into the three-mode system, but the all-autonomy option never went away.
Auto-review is the mode Cursor recommends for regular work. Run Everything belongs in a disposable environment, not a repo you'd mind losing.
Configuring the terminal allowlist
Safety-relevant policy lives in permissions.json, checked at two scopes:
~/.cursor/permissions.json— applies globally, per-user<project-dir>/.cursor/permissions.json— project-specific, checked into the repo
{
"terminalAllowlist": ["git", "npm:install*", "cargo build"],
"mcpAllowlist": ["github:*", "linear:list_issues"],
"autoRun": {
"allow_instructions": ["Read-only git commands can run without approval."],
"block_instructions": [
"Any command matching rm -rf, git push --force, or a database drop should require approval.",
"Piping a downloaded script into a shell (curl | bash, wget -O- | sh) should require approval."
]
}
}
terminalAllowlist accepts command prefixes with optional glob-style argument matching ("npm:install*"). autoRun.block_instructions is plain-English guidance the Auto-review classifier weighs — treat it as a steering signal, not enforcement, the same way you'd treat a code review comment rather than a compiler error. Per-user and per-project files are concatenated, not overridden, so a strict global file still applies inside a permissive project.
Recommended block instructions for a dangerous-command baseline
Add these as autoRun.block_instructions (or keep them out of terminalAllowlist entirely, which has the same practical effect):
rm -rf,rm -rf /, and recursive deletes outside a scratch directorygit push --force/git push --force-with-leaseto a shared branchcurl | bash,curl | sh,wget -O- | shand any download-then-execute pipeline- Database drop/truncate statements (
DROP TABLE,DROP DATABASE,TRUNCATE) - Credential/secret reads piped to network commands (
cat .env | curl ...,env | curl ...) chmod -R 777,chown -Ron system paths- Package manager commands with
--forceor that skip lockfiles (npm install --force,pip install --no-depsagainst an unpinned source)
None of these are enforced the way a permissions.deny rule is in some other agent harnesses — they steer a classifier. Pair them with the allowlist (narrow what auto-runs at all) rather than relying on block instructions alone.
What .cursor/rules can and can't do
.cursor/rules (versioned .mdc files with frontmatter, replacing the legacy single .cursorrules file) let you scope persistent instructions to the agent — "always apply," "apply to files matching a glob," "apply when the agent judges it relevant," or "apply manually via @-mention." They're useful for steering how the agent writes code, what conventions it follows, and what it should ask about before doing.
They are not a permission boundary. Cursor's own documentation is explicit that rules provide context for the agent's reasoning — they don't gate whether a tool call executes. A rule that says "never run destructive commands" can still be ignored by a poisoned prompt or an edge case the model reasons past, because nothing downstream checks the rule before the shell call runs. Put your actual enforcement in .cursor/permissions.json and Run Mode selection; use rules for behavioral guidance on top of that, not instead of it.
This mirrors a pattern across agent harnesses generally — a rules/instructions file shapes behavior, but only an allowlist, sandbox, or hook enforces it. See what agent harnesses actually are for the general shape of that distinction, and Cursor vs Claude Code vs Copilot: agent safety compared for how the same allowlist-vs-rules split shows up across all three products.
Sandboxing: the boundary underneath the settings
Cursor's sandbox (configured via .cursor/sandbox.json) constrains what a command can actually reach — workspace read/write or read-only modes, network allow/deny lists — independent of whether the command was allowlisted or classifier-approved. Auto-review uses the sandbox when a command can be sandboxed at all; some commands and platforms fall straight through to the classifier without one.
Check your sandbox config isn't set to Cursor's explicit insecure_none type, which turns sandboxing off outright. A permissive allowlist combined with insecure_none means an allowlisted command has full filesystem and network reach with no containment layer behind it — the two settings compound.
Workflow habits that matter more than any single setting
- Review diffs before accepting, especially for multi-file agent turns — a destructive command is often paired with an edit that makes the intent look benign until you read the actual patch.
- Keep Run Everything out of your primary repo. Use it, if at all, in a disposable container or throwaway checkout.
- Scope the allowlist narrowly and re-check it after upgrades — Cursor's Run Mode and permissions system changed meaningfully across the 1.3 → 3.6 window; a
.cursor/permissions.jsonwritten against an older version may not reflect current field names. - Treat
.cursor/rulesas intent, not control — write the constraint you actually need intopermissions.json, then use rules to explain why. - Don't assume MCP tools are safer than shell commands. Auto-review routes MCP calls through the same allowlist → sandbox → classifier pipeline as terminal commands; an unreviewed MCP tool has the same blast radius as an unreviewed shell command.
Where Beam fits — and where it doesn't
Beam is a local-first, privacy-first observability prototype, not a Cursor plugin. Per apps/sentinel-collector/README.md, its collector binds to 127.0.0.1:4319, stores events in NDJSON under apps/sentinel-collector/.data (directory mode 0700, files 0600), and redacts known credential formats before persistence. It never installs or enforces anything on an agent's behalf.
Concretely, that means:
- Beam has a documented direct integration for Claude Code — a CLI hook command that accepts
PreToolUse/PostToolUseJSON on stdin and forwards it to the collector. The README does not document an equivalent Cursor-specific hook, so treat Beam's Cursor coverage as whatever reaches its generic/ingestor OTLP/v1/logsendpoints through Numbat or a custom forwarder — not a first-class Cursor integration on par with Claude Code today. - Beam's skill/MCP scanner checks a
SKILL.mdor MCP config file against 11 heuristic patterns — including deletion, downloaded/encoded execution, and credential-delivery patterns — before you run it, the same category of risk ascurl | bashor a.cursor/rulesfile poisoned with malicious instructions. It's explicit that this is not semantic malware analysis. - Beam does not block, intercept, or approve/deny Cursor's tool calls. It has no equivalent of
permissions.json's allowlist or the Auto-review classifier. If a command runs, Cursor's own Run Mode and sandbox decided that — Beam's value is the after-the-fact, on-device record of what actually happened, independent of what the chat transcript claims.
That's a meaningfully different job than the allowlist and sandbox covered above: Cursor's settings decide whether a command runs at all; Beam gives you a local, redacted timeline of what ran, for review after the fact. Neither replaces the other.
Limitations, stated plainly
- Cursor's
block_instructionsare classifier guidance, not deterministic enforcement — the documentation itself frames Auto-review as risk reduction, not a guarantee. .cursor/rulescannot stop a command from executing; they can only shape the reasoning that leads up to it.- Cursor's sandbox is optional per command and per platform, and can be disabled entirely via
insecure_none. - Beam's heuristic scanner catches known dangerous shapes, not novel ones, and its Cursor integration is not as directly documented as its Claude Code hook — verify what's actually reaching the collector before relying on it as a complete record.
Frequently asked questions
Does Cursor still have a command denylist?
No. It was deprecated in release 1.3 after researchers showed it was bypassable via obfuscation, subshells, wrapper scripts, and quote-escaping. Current guidance is an allowlist (terminalAllowlist) plus classifier steering (autoRun.block_instructions) in .cursor/permissions.json.
What happened to YOLO mode?
Renamed Auto-run, then folded into three Run Modes — Allowlist, Auto-review, and Run Everything. Run Everything is the full-autonomy mode that YOLO mode always was.
Can .cursor/rules stop a dangerous command?
Not reliably — Cursor's docs describe rules as context for the agent's reasoning, not an execution gate. Put enforcement in permissions.json and Run Mode choice instead.
Does Cursor sandbox terminal commands by default?
Only when the Run Mode permits it and the command is sandboxable, and only if .cursor/sandbox.json isn't set to the explicit insecure_none type that disables sandboxing.
Does Beam block dangerous commands in Cursor?
No. Beam observes and flags locally, per apps/sentinel-collector/README.md; it does not intercept commands. Its documented direct hook integration covers Claude Code specifically, not Cursor.
What's the safest Run Mode for everyday work?
Auto-review — allowlist first, sandbox when possible, classifier review otherwise. Reserve Run Everything for disposable environments.
Summary and related reading
Cursor's terminal safety model moved from a bypassable denylist to an allowlist-plus-classifier system (.cursor/permissions.json, Run Modes) paired with optional sandboxing. .cursor/rules shapes behavior but doesn't enforce it. None of these are a substitute for reviewing what the agent actually proposes before accepting it.
- Cursor vs Claude Code vs Copilot: agent safety compared — the same allowlist/sandbox/MCP comparison across three products
- Stopping Claude Code from running dangerous commands — the equivalent guide for Claude Code's permission modes and Bash sandbox
- What are agent harnesses? — the general shape of allowlists, sandboxes, and hooks across agent tooling
- MCP security: a practical guide — tool poisoning risk, relevant to Cursor's
mcpAllowlist - Vibe coding security checklist — habits that apply regardless of which agent you're running
- Primary sources: Cursor Run Modes, Cursor permissions reference, Cursor sandbox reference, Backslash Security's denylist research
Cursor setting names, Run Mode behavior, and deprecation details reflect Cursor's public documentation and Backslash Security's published research as of September 2026 — verify against current docs before relying on a specific field name, since Cursor's permission system has changed materially between versions. Beam capability claims reflect apps/sentinel-collector/README.md as of Sentinel collector v0.1, a local prototype.