# Malicious code hidden in repo assets

First-line imports, bundled node_modules, eval of reassembled asset fragments, and oversized extension bundles

_Area: Software supply chain and CI/CD. Seen in 3 disclosed reports; latest 2026-10-30. Updated 2026-11-02._

## How it works
A delivered project or package looks legitimate, but executable code is smuggled inside something a reviewer treats as inert: a bundled dependency, an image comment, or a minified extension bundle. The payload runs when the asset is loaded or the module is imported, not when a user clicks anything. The broken assumption is that non-code assets and vendored dependencies are safe to trust and skip. In E1 the first line of `server.js` imports a package (`colorized_terminal` 2.1.0) that ships inside `node_modules` rather than the registry; importing it launches a detached implant from `node_modules/.cache/`. In E2 Base64 fragments in SVG comments are reassembled by sort order, custom-decoded, and `eval()`'d on every server start. In E3 a ~7KB loader is embedded in the legitimate `extension.js` and runs on module load under plain Node.js, with no IDE API calls.

## Where it shows up
- First-line or top-of-file imports of packages not in the lockfile or registry, or vendored under `node_modules`/`.cache`.
- `eval`/`Function` fed by a custom decoder, especially over data read from non-code files.
- Base64 or hex chunks in SVG/PNG comments, locale files, or READMEs, reassembled by `sort()` or filename order.
- Extension or bundle files noticeably larger than the prior release [E3](https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-claude-code-extension-trojanized.md).
- README text forbidding edits or AI review of one specific file [E1](https://bugbountylibrary.com/r/blog%3Asecurelist-com-mirage-kitten-new-backdoors-noderabbit-pollcat-121244.md).
- Git hooks (`post-merge`, `post-checkout`) or persistence artifacts added by a project [E1](https://bugbountylibrary.com/r/blog%3Asecurelist-com-mirage-kitten-new-backdoors-noderabbit-pollcat-121244.md).

## How to review
Trace every import to its resolved file and confirm it exists in the registry at the stated version. The invariant: no code executes at load time from an asset that is not itself reviewed source. Grep for `eval`/`Function`/`child_process`/`spawn` and follow each to its data source; if the data comes from an image, comment, or sorted fragments, treat it as code. Diff bundle sizes against adjacent clean versions and sandbox-load the extension to see what runs without IDE APIs [E3](https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-claude-code-extension-trojanized.md). Check for hooks and persistence paths after install.

## How finders spotted it
- Threat hunting flagged a coding-challenge archive; the README's insistence that `server.js` was bug-free and its ban on AI assistants drew attention to the first-line import of an unknown bundled package [E1](https://bugbountylibrary.com/r/blog%3Asecurelist-com-mirage-kitten-new-backdoors-noderabbit-pollcat-121244.md).
- A Slack #jobs lure led to collecting the repos; tracing the `eval` chain reached SVG comment steganography, then seven sibling repos with zero AV detections [E2](https://bugbountylibrary.com/r/blog%3Aelastic-co-security-labs-threat-command-contagious-interview-malware-svg-steganography.md).
- Registry and sandbox analysis: `extension.js` was ~7KB larger than the prior release, and sandbox telemetry showed the payload running under plain Node.js with no VS Code APIs, prompting comparison against clean 2.1.312/2.1.314 builds [E3](https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-claude-code-extension-trojanized.md).

## Variants seen
- Bundled npm package imported on line one, implant in `.cache` [E1](https://bugbountylibrary.com/r/blog%3Asecurelist-com-mirage-kitten-new-backdoors-noderabbit-pollcat-121244.md).
- Steganographic Base64 in SVG comments, reassembled and `eval`'d at startup [E2](https://bugbountylibrary.com/r/blog%3Aelastic-co-security-labs-threat-command-contagious-interview-malware-svg-steganography.md).
- Loader injected into a legitimate extension bundle, runs on module load [E3](https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-claude-code-extension-trojanized.md).
- Fake VS Code extension plus Git hook injection for persistence [E1](https://bugbountylibrary.com/r/blog%3Asecurelist-com-mirage-kitten-new-backdoors-noderabbit-pollcat-121244.md).

## Impact and severity
All three yield code execution on developer machines. E1 and E2 steal credentials, wallets, and source, and E2's access enables downstream supply chain attacks. E3 beacons environment variable names to reveal which CI/CD, cloud, and registry tokens were present, and its persistence survives uninstall. Severity is high because the foothold sits on the machine that builds and signs releases.

## Why fixes fail
E3's persistence artifacts (LaunchAgent, scheduled task, cron `@reboot`) survive extension uninstall, so removing the package does not remove the implant.

## Seen in real software
Open-source packages and projects, and products, where this pattern was found. If the target runs one, compare the version it runs with the fix.
- **Claude Code VS Code extension** (extension.js) 2.1.313, fixed in 2.1.314: Trojanized Claude Code Extension Delivered Persistent SSH Backdoor to Developer Machines. Report: https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-claude-code-extension-trojanized.md

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Asecurelist-com-mirage-kitten-new-backdoors-noderabbit-pollcat-121244.md
- E2: https://bugbountylibrary.com/r/blog%3Aelastic-co-security-labs-threat-command-contagious-interview-malware-svg-steganography.md
- E3: https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-claude-code-extension-trojanized.md
