BPF sandbox does not propagate user command rejections as session-scoped blocklist rules

Resolved 💬 3 comments Opened Mar 14, 2026 by trademomentumllc Closed Apr 12, 2026

Security Bug

When a user rejects a tool call (Bash command), the rejection is treated as a UI-layer event only. The BPF sandbox has no awareness that the rejection occurred. The agent can immediately resubmit a structurally identical command pattern, and the sandbox will allow it to execute.

This is a defense-in-depth gap: user rejections are threat intelligence that should propagate down to the sandbox layer, not just up to the AI.

Reproduction

  1. Agent submits a Bash command containing newlines separating multiple commands
  2. User rejects the command with reason: "Command contains newlines that could separate multiple commands"
  3. Agent submits another command with the same newline-separated pattern
  4. BPF sandbox allows it to execute without flagging
  5. The malformed command creates hung processes (zombie shells with open pipes)

Observed Impact (real incident)

  • 3 zombie shell processes created from malformed multi-line commands
  • 2 compiled binaries stuck in infinite loops at 100% CPU for 50+ minutes
  • Processes had to be manually discovered via ps aux and killed with kill -9
  • The malformed commands produced unpredictable shell behavior: arguments bled across line boundaries, pipes connected to wrong processes

Root Cause

Three gaps in the security architecture:

  1. No rejection memory in the sandbox: Each tool call is evaluated independently. The BPF layer has no awareness that a prior command was rejected. A rejection is a UI event, not a security event.
  1. No newline injection detection: The BPF filter evaluates the command as a single string. It does not parse for newline characters that split one apparent command into multiple actual commands. This is a shell injection vector.
  1. No structural pattern matching on rejections: If a user rejects command A, and the agent submits command A' (structurally identical), there is no heuristic to flag the similarity. The rejection signal is lost.

Expected Behavior

  1. When a user rejects a command, the rejection reason and command pattern should be added to a session-scoped blocklist in the BPF sandbox
  2. Subsequent commands matching the rejected pattern should be automatically blocked without requiring user intervention
  3. Commands containing newline characters that separate multiple operations should be flagged by default as potential injection vectors
  4. In restrictive permission modes (e.g., Parrot), rejected patterns should receive elevated scrutiny

Severity

High. This allows the agent to bypass an explicit user denial. The user said no, the system said yes. In a security context, this means the human-in-the-loop control is cosmetic — the agent can retry until the user misses it, or (as in this case) simply resubmit immediately.

Environment

  • Claude Code: 2.1.76
  • OS: Debian Linux (6.17.13+2-amd64)
  • Shell: bash
  • Permission mode: default

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗