Catch malware and planted exploits in untrusted code — any repo, package, archive, zip, or folder someone hands you — before you open, install, or build it. Includes an automatic agent hook that scans and blocks before an AI assistant runs unknown code on your machine.
A read-only scanner plus the research behind it: the many ways code gets weaponized when a stranger shares it (fake recruiter "assessments", malicious packages, poisoned templates, untrusted PRs, AI-suggested dependencies, and prompt-injection aimed at the AI reviewing the code), each with a detection signature and a fix.
It started with two real, confirmed malware deliveries to a job seeker four days
apart, using completely different mechanisms — neither executed. Those two cases
(see recruiter-scam-casebook.md, companies anonymized) are the origin; the
catalog and scanner generalize the lesson to any untrusted code.
| If you want… | Read |
|---|---|
| The story, with diagrams | blog/blog-post.md |
| The two real cases, in detail | recruiter-scam-casebook.md |
| The full taxonomy of attacks + fixes | blog/threat-catalog.md |
| To scan code someone sent you | skills/repo-threat-scan/ |
| To auto-protect an AI agent | skills/repo-threat-scan/hooks/ |
| To see the attacks execute (safely) | lab/ |
recruiter-scam-casebook.md the two confirmed cases (anonymized)
blog/
blog-post.md the writeup, with mermaid diagrams
threat-catalog.md 11 categories of planted exploits + detection + fixes
payload-anatomy.md loader -> infostealer -> RAT, libraries, review methods
decoy-package-teardown.md dissection of the malicious npm package
mitigations.md layered defences, 5-min checklist -> ecosystem fixes
resources.md annotated authoritative sources
data/
recruiter-scam-findings.json structured: cases, TTPs, detection rules, IOCs
iocs.csv flat indicator list
lab/
01-git-hook / 02-postinstall / 03-build-config safe defanged demos (canaries)
scanner/ early rule scanner (RS-001..011)
skills/
repo-threat-scan/ the full scanner, the OWASP-LLM01 guardrail, and hooks
Works in any AI coding agent (Claude Code, Cursor, Copilot, Windsurf, Cline, Zed, and ~40 more) via the Agent Skills open standard:
npx skills add krushiraj/code-threat-scan # pick agents interactively
npx skills add krushiraj/code-threat-scan -g # install globally
npx skills add krushiraj/code-threat-scan --list # just list what's insideThen add the automatic guard (see below), or use the scanner directly — it also works standalone with no AI involved.
skills/repo-threat-scan/scan.sh is a read-only, offline triage for any untrusted
code. It never installs, builds, clones, opens, or executes the target.
# get the code WITHOUT cloning (a clone/checkout can fire git hooks)
gh api repos/OWNER/REPO/tarball/BRANCH > /tmp/r.tgz # or download the zip
mkdir /tmp/r && tar xzf /tmp/r.tgz -C /tmp/r --strip-components=1
skills/repo-threat-scan/scan.sh /tmp/r --deepIt flags armed git hooks, editor auto-run (VS Code folderOpen, devcontainers,
.envrc), committed registry tokens, install- and build-time code execution,
CI/CD pwn-request & injection, Trojan Source unicode, curl|sh droppers and
obfuscated payloads, hidden/typosquatted/unresolvable dependencies, app-level
backdoors, and prompt-injection text that tries to trick an AI reviewer into
skipping the audit — then gives a DO-NOT-RUN verdict. It catches both real
cases and stays quiet on clean repos.
Install the PreToolUse hook so protection is automatic: when an agent is about to
clone/install/build/run unknown code, it scans first and blocks on hard
malware signatures, letting clean code through with no friction.
skills/repo-threat-scan/hooks/install.sh # Claude CodeThe hook is a tiny adapter around scan.sh and works in any agent harness
that can run a command before tool execution — see skills/repo-threat-scan/hooks/README.md.
If you installed via npx skills, the hook installer lives next to the skill in
your agent's skills directory (e.g. ~/.claude/skills/repo-threat-scan/hooks/).
The two attacks shared no code — git hooks vs a poisoned npm dependency — but an
almost identical social setup: unsolicited recruiter, a real company's name
borrowed, infrastructure created days earlier, a polished assessment, and a
mandatory step that runs code. Detect on the setup, not the mechanism. And
npm install --ignore-scripts, the standard advice, does not stop build-time
execution — which is exactly how one of the two worked.
Dual-licensed, © Krushi Raj Tula:
- Code (scanner, hooks, lab, scripts, data) — MIT (
LICENSE-CODE) - Writing (
blog/, casebook, docs) — CC BY 4.0 (LICENSE-WRITING)
See LICENSE for the summary.
Defensive research. Company names are anonymized (the impersonated companies are
innocent third parties). The demos in lab/ are deliberately harmless (they drop
a PWNED_* canary, never real payloads). Indicators are published so others can
defend. Nothing here is a working weapon.