anthropics / anthropics/claude-agent-sdk-python

[SECURITY] Edit tool reads file content before PreToolUse hook validation, allowing content probing

Aperta
#604 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Python
Stelle
8.1k
Fork
1.3k
Merge medio
2g 31m
PR unite (30g)
1

Descrizione

## Summary

The Edit tool reads file content to validate `old_string` parameter **before** PreToolUse hooks are executed. This allows attackers to probe the content of files outside allowed directories by observing error messages, even when PreToolUse hooks are configured to block such access.

## Vulnerability Details

### Current Behavior

When an Edit operation is attempted with an `old_string` that:
1. Has multiple matches in the file → Returns "Found X matches" error
2. Does not exist in the file → Returns "String not found" error

**The file content is read before PreToolUse hooks can validate the file path.**

### Attack Vector

An attacker can probe file content outside allowed directories:

1. **Test for string existence**: Use `old_string="secret_api_key"` → If "String not found", the string doesn't exist; if "Found X matches", it does
2. **Enumerate file content**: Use common strings (`"password"`, `"token"`, `"key"`) to discover what's in the file
3. **Bypass security boundary**: Even though the edit is ultimately blocked, the information leak has already occurred

### Proof of Concept

1. Configure a PreToolUse hook to restrict file access to a specific directory:

```python
async def edit_only_cwd_hook(hook_input: HookInput, _session_id: str | None, _ctx: HookContext):
cwd = Path(hook_input["cwd"])
tool_input = hook_input.get("tool_input", {})
file_path_str = tool_input.get("file_path", "")

try:
file_path.relative_to(cwd)
except ValueError:
return SyncHookJSONOutput(decision="block", reason="...")
return SyncHookJSONOutput()

hooks = {
"PreToolUse": [
HookMatcher(matcher="Edit", hooks=[edit_only_cwd_hook])
]
}

```

2. Attempt to edit a file **outside** the allowed directory with a unique string:

```
Edit tool:
file_path: "/etc/passwd" (or any restricted file)
old_string: "root"
new_string: "hacked"
```

3. **Result**: Returns "Found X matches of the string to replace..." error

**The error message confirms the string "root" exists in the file, leaking information about file content.**

### Expected Behavior

PreToolUse hooks should be executed **before** any file content is read. The validation order should be:

1. ✅ PreToolUse hook validates file path
2. ✅ Hook blocks access to restricted paths
3. ❌ File content is never read (currently this happens before step 1)

## Security Impact

- **Information disclosure**: Attackers can probe file content character by character
- **Security boundary bypass**: Path-based access control is ineffective
- **Credential discovery**: Can detect presence of secrets, API keys, passwords in restricted files

## Affected Components

- Tool: `Edit`
- Hook Event: `PreToolUse`
- May also affect: `Write` (similar pattern)

## Environment

- Claude Code version 2.1.50
- Claude Agent SDK Version: 0.1.39
- Platform: macOS 26.3

## Related Issues (Claude Code Repository)

- [anthropics/claude-code#24908](https://github.com/anthropics/claude-code/issues/24908) - PostToolUse/PostToolUseFailure not fired for `` responses
- [anthropics/claude-code#21460](https://github.com/anthropics/claude-code/issues/21460) - PreToolUse hooks not enforced on subagent tool calls

## Suggested Fix

The PreToolUse hook should be triggered and validated **before** the Edit tool reads the file content. Only after the hook approves the operation should the file be accessed to validate `old_string`.

---

## Alternative: Temporary Workaround

For users affected by this issue, consider:

1. **Disable Edit tool entirely** - Only allow Write tool (may have similar issue, needs verification)
2. **Use MCP filesystem tools** with path restrictions instead of built-in tools
3. **Implement additional sandboxing** at the OS level (e.g., containerization)

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.