On 8 October 2026, the worm inside tensorlake 0.5.144 added a new persistence trick. With a stolen GitHub token, StepSecurity reports, it "writes .claude/settings.json and .vscode/tasks.json files into repos it can reach, so it runs again when someone opens the project in Claude Code or VS Code." A month earlier, CVE-2026-85674 (published 4 September) showed the same idea in aider, where a repository's .aider.conf.yml can set a test-cmd that runs "at startup."
What's affected
Any repository that developers open in a tool that reads project config. These are the files to hunt:
.claude/settings.jsonfor Claude Code. It can define hooks on events such asSessionStart, anenvblock andpermissions.allowrules..mcp.json, which lists MCP servers for Claude Code to start or connect to..vscode/tasks.json, where a task with"runOn": "folderOpen"underrunOptionsruns "when the containing folder is opened.".vscode/settings.json. VS Code's docs warn that some workspace settings contain paths to executables..aider.conf.ymland a repo-root.env. Aider's docs say the.envfile can set "many general aider options" as well as keys, andAIDER_TEST_CMDis one of them.
Trust prompts help less than you'd hope here, because the worm writes into repositories you already trust. VS Code runs automatic tasks only in trusted workspaces, and you trusted your own repo long ago. Claude Code's permissions docs say that hooks in settings files run when you have trusted only a parent folder, and also run in claude -p or SDK sessions that never show the trust dialog. A CI job that runs claude -p on a pull request branch fits that second case exactly.
How to check if you're exposed
1. Search the org for the riskiest content. Code search through the API covers default branches only, so it's a first pass:
ORG=your-org
gh search code folderOpen --owner "$ORG" --filename tasks.json --json url --jq '.[].url'
gh search code hooks --owner "$ORG" --filename settings.json --json path,url \
--jq '.[] | select(.path | test("(^|/)[.]claude/")) | .url'
gh search code mcpServers --owner "$ORG" --filename .mcp.json --json url --jq '.[].url'
gh search code test-cmd --owner "$ORG" --filename .aider.conf.yml --json url --jq '.[].url'
2. Look for the worm's commits. StepSecurity says they used the author claude@users.noreply.github.com and the message "chore: update dependencies":
gh search commits --author-email claude@users.noreply.github.com --owner "$ORG"
Then list recent changes to these paths in each repository, on every branch you care about:
for p in .claude/settings.json .mcp.json .vscode/tasks.json .vscode/settings.json .aider.conf.yml; do
gh api "repos/$repo/commits?path=$p&since=2026-10-01T00:00:00Z" \
--jq '.[] | [.sha[0:8], .commit.author.email, .commit.message] | @tsv'
done
3. Sweep local clones, including branches you haven't pushed:
find ~/src -type f \( -path '*/.claude/settings*.json' -o -name .mcp.json \
-o -path '*/.vscode/tasks.json' -o -name .aider.conf.yml \) -not -path '*/node_modules/*' \
| xargs grep -lE '"hooks"|"folderOpen"|"mcpServers"|test-cmd|lint-cmd' 2>/dev/null
grep -lE '^AIDER_(TEST|LINT)_CMD' ~/src/*/.env 2>/dev/null
In any single repo, git log --diff-filter=A --format='%h %ae %s' -- .claude .vscode .mcp.json .aider.conf.yml shows who first added each file. Read every hit the way you'd read a shell script from a stranger.
What to do now
-
Require review on these paths. Add owners in
.github/CODEOWNERS, where a pattern like.claude/matches that directory anywhere in the repo:.claude/ @your-org/security .vscode/ @your-org/security .mcp.json @your-org/security .aider.conf.yml @your-org/security /.github/ @your-org/securityThen enable "Require review from Code Owners" in branch protection. CODEOWNERS only gates pull requests, so also require a pull request before merging. Otherwise a stolen token with push access commits straight past it.
-
Restrict hooks and MCP servers with Claude Code managed settings. Put a
managed-settings.jsonin/Library/Application Support/ClaudeCode/on macOS,/etc/claude-code/on Linux and WSL, orC:\Program Files\ClaudeCode\on Windows:{ "allowManagedHooksOnly": true, "allowManagedMcpServersOnly": true, "allowedMcpServers": [{ "serverName": "github" }] }allowManagedHooksOnlyblocks user, project and local hooks while managed hooks still run. The MCP pair makes the managed allowlist the only one that counts. -
Run headless agents without project config. For
claude -pon code you didn't write, the docs recommend--setting-sources useror--bare, or--settings '{"disableAllHooks": true}'for that run. SettingdisableAllHooksin your user settings isn't enough, because project settings take precedence and can set it back. To open a suspect repo interactively,claude --safe-modeskips hooks and MCP servers from your own config and the project, though managed policy still applies. -
Keep VS Code automatic tasks off. Set
"task.allowAutomaticTasks": "off"in user settings, and pick Disallow if VS Code asks. Don't trust broad parent folders like~/src, since subfolders inherit that trust. -
Pin aider to your own config.
aider --config ~/.aider.conf.ymlloads only that file. Aider still reads a repo-root.env, so keep theAIDER_grep above in your routine. -
Clean up properly. Delete planted files in a reviewed pull request, check other branches, and treat anyone who opened the repo after the planting commit as possibly compromised.
Why it matters
Agent config files are executable code with a JSON or YAML extension. They live in the repo, travel with every clone and run with the developer's credentials. Tensorlake shows attackers have noticed that this is better persistence than a cron job: it reinfects whoever opens the project next.
The fix is ordinary repository hygiene applied to a new set of paths. Give them owners, require review and decide centrally which hooks and servers may run at all.
Try it yourself
Run the step 1 searches against your own org and count the hits. For each one, decide whether the file should exist, who owns it and whether it runs a command. Then see how a pull request gate can flag changes to these paths before merge.
Click through it at your own pace, or open it full screen.
Quick check
Why doesn't workspace trust stop a planted tasks.json?
The worm commits into repositories developers already trust. VS Code blocks automatic tasks only in untrusted workspaces, so the task.allowAutomaticTasks setting is the control that matters.
Do Claude Code project hooks run in claude -p sessions?
Yes. The docs say hooks in settings files are used in claude -p and SDK sessions even when the folder was never trusted. Use --setting-sources user, --bare or a disableAllHooks override for untrusted code.
Is CODEOWNERS enough to stop a stolen token?
No. It only applies to pull requests. Pair it with branch protection that requires a pull request before merging.
Sources
- StepSecurity: tensorlake npm package compromised
- GitHub Advisory GHSA-rqxj-g25x-4v9v
- NVD: CVE-2026-85674
- Claude Code docs: Permissions and workspace trust
- Claude Code docs: Settings reference
- Claude Code docs: Managed settings
- Claude Code docs: Hooks
- Claude Code docs: CLI reference
- VS Code docs: Tasks
- VS Code docs: Workspace Trust
- Aider docs: YAML config file
- Aider docs: Config with .env
- Aider docs: Options reference
- GitHub Docs: About code owners
- GitHub REST API: Commits
- GitHub CLI manual: gh search code, gh search commits
- Git docs: git log