Desoul Review English

← Hướng dẫn

Dùng hook chặn Claude Code đọc file bí mật của bạn

Việc cần làm là giữ Claude Code tránh xa file .env, SSH key và credential của cloud. Một hook PreToolUse nhìn thấy mọi lần gọi tool trước khi nó chạy, và exit code 2 sẽ chặn lệnh đó. Ngày 5 và 6/11/2026 mình test hai bộ guard public, đặt cạnh hai guard của chính mình (một cái chặn đọc file bí mật, một cái chặn lệnh git nguy hiểm), bằng cách cho tất cả chạy cùng một loạt lần gọi tool giả.

Mình test thế nào

Không có secret thật, không đụng home folder thật. Mỗi hook chạy trên một bản copy riêng với HOME giả, mỗi dòng stdin là một JSON event, đúng kiểu Claude Code gọi nó. Mình ghi lại exit code.

printf '{"tool_name":"Read","tool_input":{"file_path":"/work/app/.env"}}' \
  | HOME=FAKE_HOME bash COPY_OF_HOOK.sh

24 lần gọi giả được đưa cho guard trong disler/claude-code-hooks-mastery và guard của mình. 33 lần gọi giả đưa cho emaarco/agento-patronum, chạy một lần với hook plugin cũ và một lần với hook hiện tại. Tác giả đã gộp repo này vào emaarco/hogwarts nên URL cũ không còn dùng được. Hai hook cho kết quả y hệt nhau.

Guard của hooks-mastery so với của mình

Không guard nào phủ hết. Của họ mạnh hơn ở mấy lệnh xoá, của mình mạnh hơn ở chuyện đọc credential qua shell.

agento-patronum: chặn file tốt, chặn shell yếu

Nó có sẵn 12 rule: .env, .env.*, *.pem, *.key, ~/.ssh/*, ~/.aws/credentials, ~/.aws/config, ~/.docker/config.json, ~/.kube/config, ~/.npmrc, ~/.pypirc và lệnh printenv. Bản cập nhật ngày 10/11 thêm năm rule nữa: ~/.config/gh/hosts.yml, ~/.config/glab-cli/config.yml, ~/.git-credentials, ~/.netrc và ~/.claude/.credentials.json.

Ngày 14/11/2026 mình chạy lại các lần gọi giả vào hook đã cập nhật đó, trong một sandbox macOS: không có mạng, chỉ được ghi vào hai folder tạm, HOME giả, môi trường trống và giới hạn 10 giây CPU. Mình đọc hết 163 dòng của hook trước khi chạy. Danh sách 33 lần gọi ban đầu không được lưu lại, nên mình dựng lại từ ghi chú (32 lần gọi cộng 3 lần mình ghi riêng, nên không phải đúng y bộ cũ). Mọi kết quả bên dưới đều giữ nguyên, trừ chỗ có nói khác.

Với shell thì cách nào ổn, và phải trả giá gì

Bạn so trên toàn bộ text của lệnh, đừng chỉ nhìn chữ đầu tiên. Guard git của mình chạy regex trên cả câu lệnh, nên bắt được cd x && git push, thứ mà rule chỉ xét phần đầu sẽ bỏ sót. Cái giá là báo nhầm. Trong lúc test, guard của mình chặn một lệnh chỉ có chữ "git push" nằm trong một chuỗi trong ngoặc, và chặn một lệnh khác chỉ vì nhắc tới .env trong một cái nhãn. Guard của hooks-mastery cũng dính đúng kiểu báo nhầm đó.

Nếu bạn tự viết

  1. Cho Grep và Glob vào matcher, đừng chỉ có Read, Edit và Bash.
  2. Với Bash, so trên toàn bộ text của lệnh, và chấp nhận đôi lúc báo nhầm.
  3. Thiếu file rule, file rule hỏng, hoặc input không phải JSON hợp lệ thì chặn hết.
  4. Mỗi lần chặn đều kèm lý do mà người đọc hiểu được, và ghi log mỗi lần thành đúng một dòng.
  5. Test bằng lần gọi giả như ở trên, và xem exit code.

Hook không thay được deny rule trong settings. Chính README mới của patronum có ghi là deny rule cho Read còn được đưa vào sandbox của Claude Code. Bạn dùng cả hai.

Các tool được nhắc tới trong bài