False Positive: Security Hook Blocking Write Tool on Non-Code Files

Resolved 💬 9 comments Opened Nov 1, 2025 by jagan-nuvai Closed Jan 30, 2026

False Positive: Security Hook Blocking Write Tool on Non-Code Files

Summary

The PreToolUse:Callback security hook is incorrectly blocking the Write tool when creating markdown documentation files, triggering a command injection warning despite no shell execution occurring.

Environment

  • Platform: macOS (Darwin 24.3.0)
  • Model: claude-sonnet-4-5-20250929
  • Claude Code: 2.0.31

Issue Description

When attempting to write a markdown file using the Write tool, a security hook is incorrectly blocking the operation with this error:

Write(00-introduction.md)
  ⎿  PreToolUse:Callback hook returned blocking error
  ⎿  Error: ⚠️ Security Warning: Using child_process.exec() can lead to command injection vulnerabilities.

     This codebase provides a safer alternative: src/utils/execFileNoThrow.ts

     Instead of:
       exec(`command ${userInput}`)

     Use:
       import { execFileNoThrow } from '../utils/execFileNoThrow.js'
       await execFileNoThrow('command', [userInput])

Problem

  1. False Positive Detection: The Write tool does not use child_process.exec() - it's a file system operation
  2. Incorrect Context: The security warning references source code patterns (src/utils/execFileNoThrow.ts) but is triggered on markdown file creation
  3. Blocks Legitimate Operations: Prevents writing documentation and non-executable files
  4. Confusing Error Message: Suggests code-level fixes for a file operation that doesn't involve shell execution

Expected Behavior

The security hook should:

  • Only trigger on actual shell command execution (Bash tool, exec calls, etc.)
  • Allow Write tool operations on non-executable files (.md, .txt, .json, .yaml)
  • Distinguish between file content and shell commands
  • Not block documentation file creation

Actual Behavior

The hook incorrectly:

  • Treats markdown file writes as potential command injection vectors
  • Blocks the Write tool based on filename or content patterns
  • Provides irrelevant remediation advice for file operations

Reproduction Steps

  1. Use the Write tool to create a markdown file:

``
Write("/path/to/00-introduction.md", <markdown_content>)
``

  1. Observe the PreToolUse:Callback hook returned blocking error
  2. Note the command injection warning despite no shell execution

Proposed Solutions

Option 1: Scope Hook to Bash Tool Only

// Only apply command injection checks to Bash tool
if (tool.name === 'Bash' && containsUnsafePattern(tool.command)) {
  return blockingError;
}

Option 2: Whitelist Safe File Extensions

// Allow Write operations on documentation files
const safeExtensions = ['.md', '.txt', '.json', '.yaml', '.yml', '.toml'];
if (tool.name === 'Write' && isSafeExtension(tool.file_path)) {
  return allowOperation;
}

Option 3: Content-Based Analysis

// Only check for command injection in shell contexts
if (tool.name === 'Bash' || isShellExecution(tool)) {
  return analyzeCommandInjection(tool);
}

Impact

  • Severity: Medium-High
  • Affected Users: Anyone using Claude Code to create documentation or configuration files
  • Workaround: None available - hook blocks the operation entirely
  • Frequency: Occurs on every Write tool invocation for certain file patterns

Additional Context

This appears to be a hook configuration issue where:

  1. The pattern matching is too broad (possibly regex matching on content vs. context)
  2. The hook doesn't differentiate between tool types (Write vs. Bash)
  3. Security checks intended for shell execution are applied to file I/O

Related Issues

  • This may affect other file operation tools (Edit, NotebookEdit)
  • Could block legitimate workflows involving file generation
  • May impact automated documentation generation

Requested Fix

Please update the security hook to:

  1. Only apply command injection checks to shell execution contexts (Bash tool)
  2. Exclude file operation tools (Write, Edit) from shell security checks
  3. Add tool-specific validation logic
  4. Improve error messages to indicate which tool/operation triggered the block

View original on GitHub ↗

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