npm Backdoor in LinkedIn Job Offer Caught by Pi Agent
Key insights
- The backdoor in `app/test/index.js` was 250 lines disguised as a test suite, assembling its C2 URL from separate string variables to evade scanning.
- npm's `prepare` hook executes automatically on every `npm install`, meaning the payload fires without any developer action beyond cloning and installing.
- The attacker stole two real identities: a recruiter persona from an arts journalist and commit attribution from a legitimate full-stack developer.
Why this matters
The attack targets a core developer workflow, specifically cloning unfamiliar repositories and running npm install to evaluate them, creating a broad threat surface among technical professionals who routinely handle third-party code. By splitting the command-and-control URL across string variables rather than embedding it in plaintext, the backdoor evades basic static analysis tools that scan for literal suspicious URLs in source code. The incident shows that sandboxed AI agents with read-only file constraints can detect obfuscated payloads that developers under social-engineering pressure are likely to miss during manual review.
Summary
A fake LinkedIn recruiter asked Roman Imankulov to review a GitHub repository. The repo contained a backdoor in `app/test/index.js`, 250 lines disguised as a test suite, assembling a command-execution URL from string fragments and firing automatically via npm's `prepare` hook.
The recruiter's identity was stolen from a real arts journalist. Commits were falsely attributed to a full-stack developer who confirmed he never touched the project.
Essentially: (Roman Imankulov, Pi agent) the attack was caught before any code executed locally.
- The C2 URL was split across string variables to evade static scanning, pointing to `https://rest-icon-handler.store/icons/77`.
- Imankulov sandboxed analysis on a throwaway Hetzner VPS, running Pi in read-only mode (`pi --tools read,grep,find,ls`).
The attack was still active at the June 15 publication.
Potential risks and opportunities
Risks
- Developers who cloned and npm-installed the repository before the June 15 post may have already executed the payload, with no public disclosure about how many were targeted by the same recruiter account
- The `prepare` hook combined with fragmented URL obfuscation is trivially replicable across any npm-adjacent project, lowering the barrier for copycat attacks targeting other developer communities
- The malicious repository was still live on GitHub at the June 15 publication date, meaning developers reached by the recruiter after that date could still be exposed without warning
Opportunities
- Sandboxed AI coding agents with read-only constraints, like Pi at pi.dev, gain a concrete publicized security use case that could accelerate adoption for third-party code-review workflows at security-conscious teams
- npm maintainers and GitHub could introduce opt-in warnings before `prepare` lifecycle hooks run from newly cloned repositories with no prior install history, closing this specific attack vector
- Threat intelligence vendors can use the publicly disclosed C2 domain (`rest-icon-handler.store`) to map campaign infrastructure and identify other malicious repositories tied to the same operator
What we don't know yet
- Whether the malicious server at `https://rest-icon-handler.store/icons/77` has been taken down or reported to infrastructure providers since the June 15 publication
- The full scale of developer targets: whether the fake recruiter account contacted others beyond Imankulov with identical or variant repositories
- The identity of the threat actor behind the campaign, including who registered the C2 domain `rest-icon-handler.store` and whether it connects to a broader attack series
Originally reported by roman.pt
Read the original article →Original headline: Fake LinkedIn Recruiter Hides npm Backdoor in GitHub Code Review Request — Developer Catches It With AI Agent Sandbox