Skip to content

feat(hooks): harden security hooks and add comprehensive test suite#48

Open
nwetzel22 wants to merge 1 commit into
FlorianBruniaux:mainfrom
nwetzel22:feature/improve-security-hooks
Open

feat(hooks): harden security hooks and add comprehensive test suite#48
nwetzel22 wants to merge 1 commit into
FlorianBruniaux:mainfrom
nwetzel22:feature/improve-security-hooks

Conversation

@nwetzel22

Copy link
Copy Markdown

Summary

  • dangerous-actions-blocker.sh: Added credential file read blocking using grep -qP with a
    negative lookahead ((?![a-zA-Z0-9._-])) so real credential files are blocked but template
    files like dotenv.py or env examples are correctly allowed
  • file-guard.sh: Split CRITICAL_PATTERNS into FILENAME_PATTERNS (basename glob match)
    and PATH_PATTERNS (substring match); added ~/.agentignore global fallback with crash-safe
    trap cleanup
  • test-hooks.sh: New 94-test suite covering destructive commands, force push, credential file
    patterns, secret patterns, false positives, bypass detection, and agentignore integration
  • .pre-commit-config.yaml: Updated default_language_version from python3.10 to python3
    for portability; fixed detect-aws-credentials to use args: [--allow-missing-credentials]
    instead of unsupported key; added missing --- document start; fixed line length violation

Test plan

  • Run bash examples/hooks/bash/test-hooks.sh — all 94 tests should pass
  • Run pre-commit run --all-files — all hooks should pass
  • Verify template files are allowed by the blocker
  • Verify real credential files are still blocked

🤖 Generated with Claude Code

- dangerous-actions-blocker.sh: add credential file read blocking via
  grep -qP with negative lookahead to prevent false positives on template
  files while correctly blocking real credential files
- file-guard.sh: split CRITICAL_PATTERNS into FILENAME_PATTERNS (basename
  glob match) and PATH_PATTERNS (substring match); add agentignore global
  fallback with crash-safe trap cleanup
- test-hooks.sh: 94-test suite covering destructive commands, force push,
  credential file patterns, secret patterns, false positives, bypass
  detection, and agentignore integration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@FlorianBruniaux FlorianBruniaux left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution — the test suite and the FILENAME_PATTERNS/PATH_PATTERNS split are genuinely useful. Two things need to be fixed before this can merge.

Blocking

1. grep -P is not portable to macOS

dangerous-actions-blocker.sh now uses:

if echo "$COMMAND" | grep -qP "${cred_regex}(?![a-zA-Z0-9._-])"; then

BSD grep (default on macOS) does not support PCRE (-P). Since Claude Code runs heavily on macOS, this will silently break the hook for a large portion of users. Replace with a portable alternative, for example:

# Two-step: match the pattern, then confirm the next char is not alphanumeric/dot/dash
if echo "$COMMAND" | grep -q "${cred_regex}" && \
   ! echo "$COMMAND" | grep -q "${cred_regex}[a-zA-Z0-9._-]"; then

Or use perl which ships on both macOS and Linux:

if echo "$COMMAND" | perl -ne "exit 0 if /${cred_regex}(?![a-zA-Z0-9._-])/; exit 1"; then

2. *.key, *.pem, *.p12 patterns — confirm still present

The original file-guard.sh CRITICAL_PATTERNS included *.key, *.pem, *.p12. The diff is truncated and those patterns are not visible in the new FILENAME_PATTERNS block. If they were dropped, private key files would no longer be protected — that's a regression. Please confirm they are still there (or add them back explicitly).


Minor

.pre-commit-config.yaml — anchor removal broadens the exclude scope

(?x)^(whitepapers/.*)$ was changed to (?x)(whitepapers/.*). Without ^, the pattern matches whitepapers/ anywhere in a path, not just at the root. Not a problem for this repo's current structure, but it silently changes semantics. If the goal was only to fix line length, keep the ^ anchor.

test-hooks.sh — missing jq dependency check

With set -euo pipefail active, if jq is not installed the script exits immediately with no useful message. A check at the top would help:

command -v jq >/dev/null 2>&1 || { echo "jq is required"; exit 1; }

test-hooks.sh header comment — em dash

# test-hooks.sh — Tests for dangerous-actions-blocker.sh

The should be a hyphen or the sentence restructured (project style convention).


Fix the two blocking items and this is good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants