Summary
PreToolUse hooks configured in ~/.claude/settings.json are not enforced when subagents spawned via the Task tool make their own tool calls. This creates a security vulnerability where restrictions that apply to the main agent can be completely bypassed by spawning a subagent.
Steps to Reproduce
- Configure a PreToolUse hook to restrict file writes outside the project directory:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit|Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/restrict-operations.py",
"timeout": 5
}
]
}
]
}
}
-
Hook script blocks writes outside project directory (exits with code 1 for unauthorized paths)
-
Try to write a file outside project with main agent:
- ✅ Correctly blocked by PreToolUse hook
-
Spawn a subagent with the same request:
Task tool with python-coder subagent
Prompt: "Create a file at /Users/username/test.py"
- ❌ Bypasses the hook - file is created successfully
Expected Behavior
PreToolUse hooks should apply recursively to all agents in the execution tree:
- Main agent's tool calls → hook enforced
- Subagent's tool calls → hook enforced
- Sub-subagent's tool calls → hook enforced
Actual Behavior
PreToolUse hooks only apply to the agent where settings.json is loaded:
- Main agent's tool calls → hook enforced ✅
- Subagent's tool calls → hook NOT enforced ❌
Security Impact
This allows complete bypass of security restrictions:
- File access controls - Can write/read files anywhere on the system
- Command restrictions - Can execute unrestricted bash commands
- Self-modification - Can modify or delete the hooks themselves
- Privilege escalation - Any security boundary can be bypassed
Attempted Workarounds
1. SubagentStart Hook
Added SubagentStart hook to intercept subagent spawning and analyze prompts for suspicious patterns. Limitation: Can only do heuristic analysis of the prompt text, cannot actually enforce tool-level restrictions within the subagent.
2. Intercept Task Tool
Added Task tool to PreToolUse matcher to block suspicious subagent prompts. Limitation: Prompt analysis is unreliable - many legitimate prompts contain file paths, and adversarial prompts can obfuscate intent.
Proposed Solutions
-
Global Hook Enforcement (Preferred)
- Hooks configured in
~/.claude/settings.json should apply system-wide to all agents
- Each subagent inherits parent's hook configuration
- Hooks execute in subagent's context when subagent makes tool calls
-
Explicit Hook Inheritance Flag
- Add
inherit: true option to hook configuration
- Allows opt-in recursive enforcement for security-critical hooks
-
Subagent Security Context
- Add security context parameter to Task tool
- Explicitly declare which hooks must be enforced on subagent
Environment
- Platform: macOS (Darwin 25.2.0)
- Claude Code Version: Latest (using claude-sonnet-4-5-20250929)
- Hook Types Affected: PreToolUse
- Tools Affected: Write, Edit, Bash, NotebookEdit (any tool called by subagents)
Related Issues
Example Use Cases Requiring This Fix
- Corporate environments - Enforce write restrictions to prevent data exfiltration
- Sandboxed execution - Prevent agents from escaping sandbox via subagents
- Code review automation - Ensure read-only analysis can't be bypassed
- Credential protection - Block access to sensitive files/directories
- Audit logging - Ensure all tool calls are logged, not just main agent
Additional Context
This is a fundamental security architecture issue. While hooks provide excellent visibility and control for the main agent, the lack of recursive enforcement makes them insufficient for security-critical use cases. Any security boundary enforced via hooks can be trivially bypassed by using the Task tool.
Summary
PreToolUse hooks configured in
~/.claude/settings.jsonare not enforced when subagents spawned via theTasktool make their own tool calls. This creates a security vulnerability where restrictions that apply to the main agent can be completely bypassed by spawning a subagent.Steps to Reproduce
{ "hooks": { "PreToolUse": [ { "matcher": "Write|Edit|Bash", "hooks": [ { "type": "command", "command": "~/.claude/hooks/restrict-operations.py", "timeout": 5 } ] } ] } }Hook script blocks writes outside project directory (exits with code 1 for unauthorized paths)
Try to write a file outside project with main agent:
Spawn a subagent with the same request:
Expected Behavior
PreToolUse hooks should apply recursively to all agents in the execution tree:
Actual Behavior
PreToolUse hooks only apply to the agent where settings.json is loaded:
Security Impact
This allows complete bypass of security restrictions:
Attempted Workarounds
1. SubagentStart Hook
Added SubagentStart hook to intercept subagent spawning and analyze prompts for suspicious patterns. Limitation: Can only do heuristic analysis of the prompt text, cannot actually enforce tool-level restrictions within the subagent.
2. Intercept Task Tool
Added Task tool to PreToolUse matcher to block suspicious subagent prompts. Limitation: Prompt analysis is unreliable - many legitimate prompts contain file paths, and adversarial prompts can obfuscate intent.
Proposed Solutions
Global Hook Enforcement (Preferred)
~/.claude/settings.jsonshould apply system-wide to all agentsExplicit Hook Inheritance Flag
inherit: trueoption to hook configurationSubagent Security Context
Environment
Related Issues
Example Use Cases Requiring This Fix
Additional Context
This is a fundamental security architecture issue. While hooks provide excellent visibility and control for the main agent, the lack of recursive enforcement makes them insufficient for security-critical use cases. Any security boundary enforced via hooks can be trivially bypassed by using the Task tool.