anthropics / anthropics/claude-code
[BUG] Sandbox silently denies mach-lookup; system tools return default values that the model reports as fact
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [ ] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
Same command, same Mac, same second. One runs in the user's terminal, one runs through
Claude's sandboxed Bash tool.
| | User's terminal | Claude's Bash tool |
|---|---|---|
| **Input** | `socketfilterfw --getglobalstate` | `socketfilterfw --getglobalstate` |
| **What happens underneath** | tool asks firewall daemon, gets answer | Seatbelt denies the mach-lookup, tool gets nothing |
| **Output** | `Firewall is enabled. (State = 1)` | `Firewall is disabled. (State = 0)` |
| **stderr** | none | none |
| **Exit code** | 0 | 0 |
| **Violations block shown to model** | n/a | none |
| **What Claude concludes** | n/a | "Your firewall is off" |
| **Truth** | firewall is on | firewall is on |
The two outputs are indistinguishable from the model's side. A denied query and a real
"off" produce the same bytes, the same exit code, and the same absence of a violations
block. The model has no signal to treat one differently from the other.
The same pattern, three more tools:
| Input | Terminal says | Sandbox says | Model concludes |
|---|---|---|---|
| `launchctl list \| wc -l` | 514 | 0 | "no launchd jobs" |
| `scutil --dns \| grep -c nameserver` | 2 | 0 | "no DNS resolvers" |
| `networksetup -listallnetworkservices` | 6 services | 0 services | "no network services" |
All exit 0, all print nothing to stderr, none attach a violations block.
# Environment
Claude Code in the desktop app, macOS 26.6.2, Apple Silicon.
`~/.claude/settings.json`: `sandbox.enabled: true`, `allowUnsandboxedCommands: false`.
Auto permission mode.
## Root cause
1. Seatbelt denies the mach-lookup to the daemon (alf, launchd, configd). By design the
denial goes only to the system log, not to the process.
2. The macOS tool ignores the failed connection and prints its zero-initialized state.
3. The harness surfaces network egress denials to the model in a `sandbox_violations`
block but not mach-lookup or file denials. The system prompt tells the model that
denials are reported, so a clean result with no block reads as a normal run.
`log show --predicate 'sender == "Sandbox"'` shows the `deny mach-lookup` entries for
each command. (Log excerpt attached.)
## Impact
Confident false statements about security posture. Real instance: Claude told the user
twice that the firewall was off and built LAN-exposure advice on it. In autonomous runs
the same pattern can drive wrong actions: "no launchd job exists, I will create one",
"no DNS configured, I will edit resolv.conf".
### What Should Happen?
## Proposed fix, in order of preference
1. Include mach-lookup and file denials in the existing `sandbox_violations` block, read
from the Seatbelt log for the command's PID.
2. Failing that, attach a generic "this command triggered N sandbox denials" marker so
the model knows to treat the output as unverified.
3. At minimum, correct the system prompt: denials other than network are not reported,
and system-state output from sandboxed commands must be confirmed outside the sandbox.
### Error Messages/Logs
```shell
```
### Steps to Reproduce
## Reproduction
Run each command through Claude's internal Bash tool, then in a plain terminal.
| Command | Claude Sandboxed Terminal | User Terminal | stderr | exit |
|---|---|---|---|---|
| `socketfilterfw --getglobalstate` | `disabled (State = 0)` | `enabled (State = 1)` | none | 0 |
| `launchctl list \| wc -l` | 0 | 514 | none | 0 |
| `scutil --dns \| grep -c nameserver` | 0 | 2 | none | 0 |
| `networksetup -listallnetworkservices` | 0 services | 6 services | none | 0 |
No `sandbox_violations` block was attached to any of these results.
`log show --predicate 'sender == "Sandbox"'` shows the corresponding `deny mach-lookup`
entries for each.
### Claude Model
Other
### Is this a regression?
I don't know
### Last Working Version
_No response_
### Claude Code Version
2.1.273
### Platform
Anthropic API
### Operating System
macOS
### Terminal/Shell
Terminal.app (macOS)
### Additional Information
The claude coding agent should be aware of the sandboxed terminal access not to treat the its own terminal output as the truth, thus, avoiding building code on top of such false information.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the listed commands through Claude's internal Bash tool and comparing them with a plain terminal. Trace the existing sandbox_violations handling, Seatbelt log collection, and system prompt guidance; done means mach-lookup or file denials are surfaced to the model, or the output is clearly marked unverified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos
- Domain
- cli, operating-systems, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100