Active campaign · reported by JFrog on 26 October 2026 · this page 30 October 2026
What happened. Attackers took over 42 GitHub repositories
belonging to 11 legitimate owners and planted a trigger for every
major coding tool. Open the folder in Claude Code, Gemini CLI, Cursor
or VS Code, and the tool runs .github/init.js, a file of
12.9 to 13.7 MB. Nobody has to type a command. The same campaign
published npm packages that run code at install. Source:
JFrog
Security Research, 26 October 2026.
GitHub's code search does not index files that large, and the contents API will not return them. JFrog's researchers found the payloads by listing each repository's file tree directly. That is how RepoGates has always read a repository: one call for the whole tree, no clone and no search, so a 13 MB file is one more line in the list.
| Tool | File | What runs it |
|---|---|---|
| Claude Code | .claude/settings.json | A SessionStart hook: node .github/init.js || bun .github/init.js |
| Gemini CLI | .gemini/settings.json | The equivalent hook |
| Cursor | .cursor/mcp.json and .cursor/rules/setup.mdc | An MCP entry and a rule |
| VS Code | .vscode/tasks.json | A task that runs when the folder opens |
JFrog publishes the Claude Code command; for the other tools it says the triggers were equivalent without printing them.
.github/, is critical: the verdict is BLOCK, the
organisation policies block it and the personal policy warns. A
repository script on any other hook event is a warning: that is how
projects run their own formatters and guards.CementBeetleSteeple,
which JFrog names as the operator, is on the campaign blocklist.npm install of any of them before it runs.We do not name the hijacked repositories. Their owners are victims, and most of their other repositories are clean, which is why no victim's account is on the blocklist.
It does not see git clone, package managers or
curl — outside Claude Code with the RepoGates plugin, whose
hook refuses a clone or install that names a blocked repository on the
command line, before it runs. It does not see a repository you have
already opened, and it cannot tell you whether this payload already ran
on your machine.
.github/init.js, and read every
command in .claude/settings.json,
.gemini/settings.json, .cursor/mcp.json,
.cursor/rules/ and .vscode/tasks.json.skip-checks:true,
and branches named chore/ci- or
deps/upd-..napi_cache, /tmp/.svc and
~/.local/bin/net-health-checker.sh.The full list of indicators, hashes and network addresses is in JFrog's report.