DEV Community

hao li
hao li

Posted on Originally published at github.com

I Built an Offline Supply-Chain Auditor for Claude Code Mods (stdlib-only Python)

Your Claude Code mods run shell commands with your privileges. A lifecycle hook is one curl | sh away from owning your machine — and the supply chain around agent plugins is actively on fire.

The receipts: AIR SkillJacking hijacked 925 skills reaching an estimated 134k agents. Plugin4Shell showed pin-swap attacks bypassing SHA-pinning on updates. Pwn2Own Ireland paid out $40k for a Codex argument-injection bug. And SKILLCLOAK research claims its cloaking techniques bypass 90%+ of existing scanners.

So I built mod-audit: a static supply-chain auditor for Claude Code Mods that runs locally, offline, with zero third-party dependencies. Just stdlib Python, 3.9+.

What it does

Four things, all offline:

1. Dangerous lifecycle hook scanning. It parses plugin.json / hooks.json / package.json hook sections and flags piped downloads (curl | sh), base64-decode-into-exec, curl --data exfiltration, reverse shells (nc -e, /dev/tcp/), sudo escalation, and destructive rm -rf — each with a severity, file:line, explanation, and fix.

2. Shell-execution patterns in TypeScript source. child_process.exec with shell: true, concatenated command strings, eval()/new Function(), dynamic require()/import(), cron/launchd persistence, and dotfile writes — the greatest-hits list of "how a mod gets a shell."

3. Env/API-key exfiltration detection. When process.env.*(API_KEY|TOKEN|SECRET|PRIVATE) shows up within a few lines of a network sink (fetch, axios, http.request…), that's a high-severity finding. Keys should never ride along in request bodies.

4. Trojanized-update diffing. This is the one I'm proudest of. You snapshot a mod right after a clean install:

mod-audit snapshot ~/.claude/plugins/my-mod --out ~/snapshots/my-mod.snapshot
Enter fullscreen mode Exit fullscreen mode

Then after every update:

mod-audit diff ~/.claude/plugins/my-mod --against ~/snapshots/my-mod.snapshot
Enter fullscreen mode Exit fullscreen mode

It compares file hashes, flags new/changed/removed files, detects hook command swaps (the pin-swap pattern), and re-runs all content rules on anything new or changed. A trojanized update lights up instead of slipping through.

5. Permissions manifest review. Over-broad grants — shell without per-action confirmation, unrestricted network, broad filesystem writes — get flagged before you approve them.

How it's different

Cloud scanners like ClawSecure Watchtower make you upload your mod source to someone else's server. Metadata reviewers like rad-security's AgentKeeper audit plugin/skill metadata but never read the TypeScript that actually executes. mod-audit is the opposite bet: local + offline + Mod TypeScript code specialist. Nothing leaves your machine.

CI-ready by design

mod-audit scan ./my-mod --format json
Enter fullscreen mode Exit fullscreen mode

Exit codes: 1 when a finding meets --fail-on (default high), 0 when clean, 2 on usage errors. Drop it in a GitHub Actions workflow or a cron job that diffs your installed mods against their snapshots nightly.

Honest limitations

It's offline heuristics, not a sandbox — pattern-based rules can miss obfuscated code and can false-positive on benign code. It never executes mod code (that's the point), so runtime-fetched payloads are out of scope. The diff is only as trustworthy as your snapshot, so take it from a clean install and store it somewhere the updater can't touch. And the TypeScript scanning is regex-based, not a real parser — a deliberate trade to stay stdlib-only and fast.

pip install mod-audit — MIT licensed, source on GitHub. If you maintain Claude Code mods, I'd love to hear what it flags on yours.


Repo: https://github.com/hahahahahahahahah6/mod-audit
PyPI: https://pypi.org/project/mod-audit/

Top comments (0)