affaan-m/ECC — better known as Everything Claude Code — has over 213,000 GitHub stars, making it one of the most-starred repositories on the platform. When something goes that viral, two security events follow automatically: people install it without reading it, and re-uploads start appearing. We looked at both.
The headline: most of the re-uploads are harmless stale copies — but one is a malware dropper, a fake "download toolkit" that ships an obfuscated LuaJIT payload and tells non-technical users to double-click it. The original repo isn't malware, but it does install a large, globally-active, auto-executing surface that most people clicking install have never reckoned with.
This is an evidence-based writeup. Every claim about a repo we name is backed by a file you can check yourself; for the re-uploads we deliberately don't name, we describe our method so you can reproduce the check. Nothing below is a how-to for abuse.
How we looked
We cloned the original plus 19 public re-uploads and, for each one, diffed the full file tree against a fresh copy of upstream (git diff --no-index) and checked the clone's HEAD commit and tree hash against upstream history via the GitHub API, then hand-read the parts that actually run on your machine: hooks/, the installer, package.json, .mcp.json, and any bundled archives. Archives were never extracted to disk: we listed their contents (unzip -l) and streamed individual files read-only (unzip -p); nothing from any repo was executed. For the original's prompt-injection surface we counted the auto-loadable instruction files and grepped the tree for injection/exfiltration and pipe-to-shell markers. One honest caveat: for the npm packages we read registry metadata, not the unpacked tarballs.
The malware clone: arabicapp/everything-claude-code
This one is unambiguous. The repo's README.md isn't the real ECC readme at all — it's a fake landing page headed "🚀 Visit Here to Download" with a button linking to a ZIP inside the repo itself, docs/code_everything_claude_3.3.zip. The instructions target exactly the people least able to spot the trap:
"Simple setup process designed for non-technical users." … "Double-click the installation file and follow the on-screen instructions."
Listing that ZIP (without extracting it) shows three files:
Launch.bat 30 bytes
luajit.exe 878 KB
x64.txt 307 KB
Launch.bat is one line — start luajit.exe x64.txt — and x64.txt is a heavily obfuscated Lua script that opens with the classic packed-loader shape:
return(function(...)return(function(x,l,k,q,H,s,j,U,o,m,G,C,y,b,Y,F,f,A,Q,u,J,h,c,T)...
A second archive buried under docs/zh-TW/skills/postgres-patterns/ repeats the pattern: Launcher.bat → start luajit.exe clx.txt, bundled with lua51.dll, a fresh luajit.exe, and a 360 KB obfuscated clx.txt. This is the textbook LuaJIT-loader delivery shape used by infostealers and similar malware: a legitimate interpreter runs an obfuscated payload, so nothing in the repo looks like an executable virus to a casual reviewer. We classified it from that structure — fake download readme, hidden second archive, obfuscated payload — not by executing or deobfuscating anything. None of this exists in the real ECC. We reported it to GitHub.
The tell, in hindsight, was structural: it's a full re-upload (not a GitHub fork) that replaced the readme with a download CTA. If a "toolkit" leads with download this ZIP and double-click it instead of clone and read, stop.
The other 18 clones: clean, but "stale" is its own risk
Here's what surprised us. We expected the clone wave to be where the malware hides. The other 18 re-uploads we checked turned out to be stale but untouched: each one matched a genuine historical state of the original byte-for-byte — no clone added or modified a single file of its own. No redirected install URLs, no curl|bash / iwr|iex, no base64 blobs, no credential access, no foreign domains. Where one differed from today's upstream — an extra MCP entry, an old hook pulling an external package — the difference traced back to an earlier upstream commit, not a clone insertion. We're not naming those accounts — there was nothing malicious to call out, and no reason to send traffic to stale copies. That's the one claim here you can't check from a link; it rests on the method described above.
But stale isn't the same as safe. A frozen re-upload keeps old behavior forever, including behavior upstream later removed for safety. If you must use a copy, freshness matters as much as cleanliness — and a re-upload that isn't a real fork will never receive a security fix.
The original: powerful by design ≠ malicious
We found no hidden phone-home and no exfiltration in the default install path. ECC is not a trojan. But "not malicious" and "low risk" are different statements.
The auto-exec surface is large and global. hooks/hooks.json registers 28 command hooks across 7 lifecycle events (PreToolUse, PostToolUse, Stop, SessionStart, SessionEnd, PreCompact, PostToolUseFailure). Each is an auto-executed node -e bootstrap; two PreToolUse hooks use the matcher *, so they fire before every tool call (four more PostToolUse hooks fire after every call), and the two bash dispatchers fan out to 10 more registered sub-hooks per Bash invocation (7 active in the default profile; 3 are strict-profile-only). On disk, scripts/hooks/ holds 48 hook scripts that can run automatically. The part that turns "large" into "risk" is the install target: per install-apply.js, the default installer writes these hooks globally into ~/.claude/, so ECC code runs automatically in every Claude Code session on the machine — not just one project.
Two design choices compound that into a real supply-chain concern:
- Each
hooks.jsonentry embeds an inlinenode -ebootstrap (generated fromscripts/lib/resolve-ecc-root.js) that resolves the plugin root dynamically — honoringCLAUDE_PLUGIN_ROOT, then searching several directories under~/.claude/and using the first match — and then loadsscripts/hooks/plugin-hook-bootstrap.jsfrom that root. The bootstrap has a path-traversal guard, but there's no integrity or signature check on the resolved root. Anyone able to write to a higher-priority location, or set that env var, can have code run on every action. -
scripts/auto-update.jsrunsgit fetch+git pull --ff-onlyand then reinstalls — with no commit-signature or pin verification. One compromised upstream commit on a repo this popular would propagate automatically.
There's also .mcp.json, which auto-starts an MCP server via npx -y chrome-devtools-mcp@latest — -y auto-confirms, @latest runs whatever the unpinned tag points to that day.
To be fair, ECC ships real mitigations: the traversal guard, hook profiles (ECC_HOOK_PROFILE), an ECC_DISABLED_HOOKS switch, correct shell-escaping in the notification hook, and a harmless echo-only postinstall. None of those change the fundamental shape: broad, global, ambient code execution.
The prompt-injection surface
ECC is huge as a content payload too. We counted 513 auto-loadable instruction files: 262 skills, 64 agents, 84 commands, 103 rules (excluding the rules index README; the widely-quoted "260+ / 64 / 84" figures check out). In its shipped state this surface is not weaponized — zero curl|bash, zero ignore previous / exfil markers across skills/ and agents/, and all 64 agents declare explicit (non-inherited) tool lists. It's a fair surface, not a hostile one — though "explicit" isn't the same as "minimal": 49 of the 64 agents — about three-quarters — are granted Bash.
The single most far-reaching artifact is skills/continuous-learning-v2/agents/observer-loop.sh. It spawns a background Claude subprocess (claude --model haiku … --print --allowedTools "Read,Write") with a prompt that explicitly switches off confirmation —
"Do NOT ask for permission, do NOT ask for confirmation … Just read, analyze, and write."
— and has it write persistent instinct files that later sessions apply automatically. As shipped it does nothing malicious, but it's a textbook indirect-injection-to-persistence shape: what one session observes can steer future sessions with no human in the loop. Worth understanding before you enable it.
A 5-point checklist before you install ECC (or any hook-heavy repo)
-
Never trust a "download this ZIP" readme. A real toolkit tells you to clone and read source — not double-click an installer. The
arabicappclone above is what the alternative looks like. -
Don't install globally. The default target
~/.claude/makes hooks fire in every session. Scope to one project and know where the installer writes. -
Audit the hooks before enabling them. 28 hooks across 7 lifecycle events run on nearly every action. Start at
ECC_HOOK_PROFILE=minimaland expand only what you understand. -
Pin everything; don't auto-update. Don't wire unsigned
git pull+ reinstall into automation, and replace@latestnpx/MCP invocations with pinned versions. - Treat community instruction files as untrusted input. 500+ auto-loadable skills/agents/commands/rules are an injection surface. Review anything that disables confirmation, spawns subprocesses, or writes persistent state first.
Why we ran this
We build ClawGuard — automated security scanning for MCP servers and AI-agent configurations, currently 225 detection patterns across 17 categories. It's the same engine behind the 31 security issues we've filed via responsible disclosure in third-party MCP repos. The checks above — hook and installer surface, prompt-injection entry points, clone and provenance verification — are exactly the class we automate. Tooling is open on GitHub as clawguard-shield; if you want it run continuously against your own agent setup, the scanner is at the link above.
The takeaway isn't "ECC is dangerous." It's that the most-starred agent-config repo on GitHub installs global, auto-executing code and ships 500+ auto-loadable instruction files — and the moment something is that popular, someone weaponizes a look-alike for the people who don't read code. Look first.
Top comments (0)