Claude Code es muy bueno ejecutando comandos. Ese es justo el problema cuando ejecuta el comando equivocado. Los hooks te dejan poner una red de seguridad que corre antes de cada acción, sin depender de que el modelo "recuerde" tus reglas.
Cómo funcionan (en 30 segundos)
- Se configuran en
.claude/settings.json, por evento (PreToolUse,PostToolUse,Notification…) y por herramienta (Bash,Write|Edit…). - El hook recibe el evento como JSON por stdin.
- Si sale con código 2, la acción se bloquea y el texto de stderr se le devuelve a Claude como motivo.
1. Bloquear comandos destructivos
.claude/hooks/bloquear-comandos-peligrosos.sh:
#!/usr/bin/env bash
entrada="$(cat)"
patrones=(
'git[[:space:]]+push[[:space:]].*(--force([^-]|$)|-f([[:space:]"]|$))'
'git[[:space:]]+reset[[:space:]]+--hard'
'DROP[[:space:]]+(TABLE|DATABASE)'
'(curl|wget)[^|]*\|[[:space:]]*(sudo[[:space:]]+)?(ba)?sh'
)
for patron in "${patrones[@]}"; do
if printf '%s' "$entrada" | grep -qiE -- "$patron"; then
echo "Bloqueado: coincide con un patrón peligroso. Pide al usuario que lo ejecute." >&2
exit 2
fi
done
exit 0
Fíjate en el detalle de --force([^-]|$): bloquea --force pero deja pasar --force-with-lease, que es la forma segura.
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/bloquear-comandos-peligrosos.sh" }
]
}
]
}
}
No olvides chmod +x y pruébalo:
echo '{"tool_input":{"command":"git reset --hard"}}' | .claude/hooks/bloquear-comandos-peligrosos.sh; echo $?
# → 2
2. Detectar secretos antes de escribirlos
Mismo patrón, pero con matcher: "Write|Edit|MultiEdit" y expresiones como AKIA[0-9A-Z]{16} (AWS), sk-ant-[A-Za-z0-9_-]{20,} (Anthropic) o gh[pousr]_[A-Za-z0-9]{36,} (GitHub). Si Claude intenta escribir una clave, recibe el mensaje "usa una variable de entorno y documéntala en .env.example" y corrige solo.
3. Formatear después de cada edición
Un PostToolUse que lee file_path del JSON y corre el Prettier/Biome del proyecto (node_modules/.bin/prettier). Siempre sale con 0: nunca bloquea, solo ordena.
Código gratis
Los hooks 1 y 2 completos, con pruebas que corren en Linux y macOS, están en GitHub con licencia MIT: https://github.com/kailucho/claude-code-hooks-seguridad
Si quieres todo armado
El Kit Claude Code en español (US$9) trae los tres hooks y uno de notificaciones, 6 skills en español (/commit, /pr, /revisar, /tests, /plan, /depurar), plantillas CLAUDE.md para React, Node y GraphQL y presets de permisos: https://luijhy.gumroad.com/l/kit-claude-code-es
¿Qué otro comando bloquearías tú? Te leo en los comentarios.
Top comments (1)
Yo no dejaría el force push solo en manos del regex, porque hay formas de forzar que no lo nombran. Probé tus dos patrones con el mismo JSON que recibe el hook:
git push origin +mainpasa, porque el + delante de la rama fuerza la actualización sin --force ni -f, ygit reset -q --hard HEAD~1también pasa, porque el patrón espera --hard justo después de reset.Mantendría el hook como aviso temprano, pero el bloqueo de verdad lo pondría donde el agente no puede editarlo: protección de rama en el remoto con los force push desactivados, que es como GitHub deja una rama protegida por defecto. Así, si el regex se queda corto, el push rebota en el servidor.