Roman Imankulov's read-only AI agent flagged a backdoor in a Node.js repo within seconds - a backdoor that would have executed on a simple npm install. The bait: a LinkedIn message from a recruiter at a small crypto startup asking him to review a public GitHub repo for a "deprecated Node modules issue." Imankulov didn't clone or install. He spun up a throwaway VPS on Hetzner, cloned the repo, and pointed a read-only agent at it with tools like grep, find, and ls. The agent stopped almost immediately at app/test/index.js.
The Trap: A Repo That Executes on npm install
The repo looked like a React frontend with a Node backend, but app/test/index.js was a 250-line file disguised as a test suite. Inside, a URL was assembled from fragments: const protocol = "https", domain = "store", separator = "://", path = "/icons/", token = "77", subdomain = "rest-icon-handler", bearrtoken = "logo"; These combine into https://rest-icon-handler.store/icons/77. Between walls of commented-out tests, the payload runs whatever the server sends back. The trigger chain is elegant and deadly. app/index.js itself runs const test = require('./test'), which loads app/test/index.js. package.json wires it all up: the prepare script runs automatically after npm install. The instruction to "check out the deprecated Node modules issue" was pure bait to get Imankulov to run npm install.
Borrowed Identities: The Real Developer and the Fake Recruiter
The commits in the repo were authored under the name and email of a real full-stack engineer with a GitHub account and long history. Imankulov messaged him, pretending to have inherited the codebase. The developer responded that he'd never worked for that company, had been impersonated on GitHub before, and was already reporting repos. The recruiter's LinkedIn profile belonged to a real arts journalist with zero technical background. When Imankulov played along and said he couldn't get the project to install, the journalist instantly turned into an expert on npm and Node versions. Same trick - borrowed identity.
A Read-Only Agent Spotted It in Seconds
Imankulov suspected something from the first messages but admits a tired or rushed day could have led to running npm install without thinking. He reports the backdoor was dressed up as sloppy beginner code; a human could have dismissed it. The read-only agent (pi with read-only tools) flagged it immediately. He reported the repo to GitHub and the recruiter to LinkedIn. So far, nothing has changed - the code is still up. If you get a LinkedIn message asking you to review a repo, a throwaway VPS and a read-only agent are cheap insurance against a backdoor that's waiting to run.
Source: A backdoor in a LinkedIn job offer
Domain: roman.pt
Comments load interactively on the live page.