← Claude Code Hooks Security Check

Why a clean scan isn't a safety guarantee

Zero findings means none of this tool's known-dangerous patterns matched the command text you pasted — not that the hooks you're about to trust are safe. Here is what a textual pattern scan can and can't see, and why the difference matters.

What "textual pattern" means here

Every check this tool runs looks for a specific, documented shape in a hook's command string: a download piped straight into a shell, a credential file read and sent over the network in the same line, environment variables dumped and sent over the network, an unguarded recursive delete, TLS verification disabled, persistence via a shell startup file or crontab, world-writable permissions, a base64-obfuscated payload executed, and a process started detached from the hook. These are common, well-known dangerous shapes — mechanized so they don't get missed on a rushed review of a hooks config someone else wrote.

What it can't see

Anything that isn't one of the specific shapes above, and anything hidden from a simple text match: a command built at runtime from a variable this tool can't see the value of, a shape phrased in a way the patterns don't recognise, a malicious MCP tool or script the command merely invokes by name without any of it appearing in the command string itself, or a legitimate-looking command whose actual danger only shows up given the environment it runs in. This tool never executes the command in a sandbox and observes what it does — it only reads the text.

This is the same reason a linter passing doesn't mean a test suite would: they check different, complementary things.

A match isn't always dangerous, either

Several patterns here are shapes shared by ordinary, safe commands. rm -rf on a build directory has the exact same shape as rm -rf on a home directory; nohup behind a legitimate long-running dev-server hook looks the same as one used to persist something unwanted. Every finding is worded as worth a look, not a verdict — reviewing the actual command in its real context is still yours to do.

What a clean scan is worth, then

It rules out the specific, common dangerous shapes above, cheaply, before you trust a hooks configuration someone else wrote or a project you just cloned — worth running on every hooks config before you let it fire unattended. Treat it as a floor: pair it with actually reading the commands, not a substitute for reading them.

Common questions

If a hooks scan comes back with zero findings, are my hooks safe?

No. A zero-finding result means none of this tool's known-dangerous patterns matched the command text you pasted -- it does not mean the hooks are safe to run unattended. The scan looks for specific textual shapes (a download piped into a shell, a credential read sent over the network, and the others it documents), not at what a command actually does when it runs, and it cannot see a shape it doesn't yet know about.

What can a textual pattern scan actually catch?

Command strings that match a documented, specific shape: a remote download piped straight into a shell interpreter, a credential file read and sent over the network in the same line, environment variables dumped and sent over the network, an unguarded recursive delete of a broad path, TLS verification disabled, persistence via a shell startup file or crontab, world-writable permissions, a base64-obfuscated payload executed, and a process started detached from the hook. These are common, well-known dangerous shapes -- mechanized so a rushed review doesn't miss one.

What can't it catch?

Anything that isn't one of the specific shapes above, and anything hidden from a simple text match: a command built at runtime from a variable this tool can't see the value of, a shape phrased in a way the patterns don't recognise, a malicious MCP tool or script the command merely invokes by name, or a legitimate-looking command whose actual danger only shows up given the environment it runs in. A textual scan cannot execute the command in a sandbox and observe what it does, and it does not try to.

Does a match always mean a command is dangerous?

No. Several patterns here are shapes shared by ordinary, safe commands -- rm -rf on a build directory has the same shape as rm -rf on a home directory; nohup for a legitimate long-running dev-server hook looks the same as one used to persist something unwanted. Every finding is worded as worth a look, not a verdict, and reviewing the actual command in context is still yours to do.

So what is a clean scan actually worth?

It rules out the specific, common dangerous shapes it checks for, cheaply, before you trust a hooks configuration someone else wrote or a project you just cloned -- the same value a linter has before a human review. Treat it as a floor: worth running on every hooks config you're about to trust, and worth pairing with actually reading the commands, not a substitute for reading them.