anthropics / anthropics/claude-code

[BUG] Sandbox silently denies mach-lookup; system tools return default values that the model reports as fact

Open
#94,612 0 comments 0 reactions 0 assignees View on GitHub
area:bash area:sandbox bug platform:macos
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.