Today in Developer Supply-Chain Attacks:
- Roman Imankulov published a first-person postmortem at roman.pt on June 15, 2026 (HN 48546294, 712 points and 148 comments at scan, top of the Hacker News front page) describing how a fake LinkedIn recruiter walked him into a public GitHub repo designed to deliver a backdoor the moment he ran npm install. The attack chain is LinkedIn (identity), GitHub (code distribution), and npm (auto-execution). The author had to use an AI code-review agent on a throwaway Hetzner VPS to flag the malicious code, because it was buried inside 250 lines of pseudo-test scaffolding and was wired to the npm 'prepare' lifecycle hook.[1]
- The recruiter claimed to be staffing a 'lead engineer' for a broken proof-of-concept at a small crypto startup, and asked Imankulov to 'check out the deprecated Node modules issue.' That single instruction was the bait: the backdoor ran via the npm 'prepare' script, which npm executes automatically after 'npm install.' All the target had to do was install the dependencies, and the rest of the chain fired on the developer's machine without any further action.[1]
- The trap was inside 'app/test/index.js', a 250-line file disguised as a sloppy test suite. The file assembled a URL from six fragments ('https' + '://' + 'rest-icon-handler' + '.store' + '/icons/' + '77'), then ran whatever the server at that URL returned. The payload was hidden between walls of commented-out tests. The commit history of the repo, 39 commits, was attributed to a real full-stack engineer who confirmed to the author that he had never worked for the company and had been impersonated on GitHub before.[1]
- The recruiter's LinkedIn profile belonged to a real, well-known arts journalist with no technical background. When the author played along and told the 'recruiter' that the project would not install, the journalist profile instantly pivoted to debating Node versions and pushed harder for the npm install. The pivot is the second identity-borrowing tell in the same attack.[1]
- As of the time of writing, the GitHub repo is still public and the LinkedIn recruiter profile is still live. The author reported the repo to GitHub and the profile to LinkedIn. The HN thread reports that nothing has changed. The persistence of the delivery infrastructure is the second shareable hook in the cycle: the platform takedown pipeline for this attack class is currently measured in 'still up' weeks, not hours.[1][2]
- This is the dominant new developer-targeted supply-chain attack class of 2026. The same attack pattern was independently documented on The Hacker News on June 15, 2026 under the headline 'North Korean Hackers Are Turning Developer Tools Into Malware Delivery Channels,' tying the LinkedIn backdoor to the Shai-Hulud worm hitting Microsoft GitHub repos, the Arch Linux AUR 1,500-package incident, and the Slack video-embed E2EE exploit. The chained-attack-surface framing (identity → distribution → auto-execute) is the privacy story. The state-aligned-targeting framing is the threat-actor story. The two are the same story at two layers.[3][4]
- Watch over the next 7 days: the first GitHub or LinkedIn public statement on the report Imankulov filed, the first major-outlet identification of the threat actor behind the rest-icon-handler.store infrastructure, the first peer-reviewed security analysis of the 'prepare'-script-as-attack-surface pattern across the npm, PyPI, and RubyGems ecosystems, and the first LinkedIn product change to employer-verified-recruiter profiles as a default (the same product change Five Eyes called for in its June 5, 2026 rare joint warning on Chinese spy recruitment via LinkedIn DMs).
The Attack Chain: LinkedIn Is the Identity Layer. GitHub Is the Distribution Layer. npm Is the Auto-Execution Layer.
Roman Imankulov, a full-stack Python developer building Smello (a local-first HTTP traffic inspector for Python), published a first-person postmortem at roman.pt on June 15, 2026 under the headline "A backdoor in a LinkedIn job offer."[1] The postmortem describes a clean, three-step attack chain that the privacy and security community had not previously seen executed end-to-end with this much fidelity. The chain is worth mapping in full because the chain is the story, and the chain is what makes this the dominant new attack class of 2026.
Step 1: Identity. LinkedIn. A "recruiter at a small crypto startup" sent Imankulov a LinkedIn message. The two exchanged a few messages over a couple of days. The recruiter described a broken proof-of-concept they needed a lead engineer for, then sent a public GitHub repo for review with the instruction to "check out the deprecated Node modules issue." The recruiter's profile was that of a real arts journalist with a long cultural background and no technical footprint. The non-technical public profile, paired with on-message technical vocabulary in DMs, is the first tell of a borrowed identity.[1]
Step 2: Code distribution. GitHub. The recruiter's bait was a public GitHub repo. The repo was structured to look like a React frontend with a Node backend. The trap was buried inside 'app/test/index.js,' a 250-line file that looked like a sloppy test suite. Inside the file, six URL fragments were assembled at the top of the script: "https" + "://" + "rest-icon-handler" + ".store" + "/icons/" + "77." The result was the URL "https://rest-icon-handler.store/icons/77."[1] The fragments looked like ordinary constants. The assembled URL did not. The author did not get a chance to see the assembled URL in context because the surrounding 250 lines of commented-out tests hid the assembly and the payload. The 39 commits in the repo were attributed to a real full-stack engineer who confirmed to the author that he had never touched the project, that he had been impersonated on GitHub before, and that he had previously had a repo taken down for the same reason. The second identity-borrowing tell.[1]
Step 3: Auto-execution. npm. The trigger is the part that turns the attack from "sneaky code" into "guaranteed execution." The repo's 'package.json' defined a 'prepare' script that ran 'node app/index.js.' npm runs the 'prepare' script automatically after every 'npm install.' 'app/index.js' then loaded 'app/test/index.js' as a module, which executed the URL assembly and the payload. The instruction to "check out the deprecated Node modules issue" was bait to get the target to run 'npm install.' Once the target ran 'npm install,' the rest of the chain fired without any further action by the target.[1]
The three layers are the same three layers as the Axios npm supply-chain attack of April 2026 (where North Korean UNC1069 hijacked the Axios package and pushed a malicious build to millions of developers), and the same three layers as the Bitwarden CLI attack of April 2026 (where a 90-minute package compromise targeted AI coding tools). The identity layer is the new piece. GitHub-as-distribution and npm-as-auto-execute have been seen before, with the attacker sitting somewhere between developer-targeted and package-targeted. The LinkedIn-as-identity-layer pivot is what makes the 2026 attack class the new attack class.[5][6]
The Defense That Actually Worked: A Throwaway VPS and a Read-Only AI Agent
The defense in the postmortem is the part of the cycle that has been the most under-shared. Imankulov did not trust the request, so he did not clone and install on his own machine. He spun up a throwaway VPS on Hetzner, cloned the repo there, and pointed an AI coding agent at it in read-only mode with only file-reading tools enabled. The command was "pi --tools read,grep,find,ls."[1] The agent stopped almost immediately at 'app/test/index.js' and flagged it as suspicious. The read-only posture is the operational key. The author used the agent specifically to review the codebase, and the agent's read-only tools meant the agent could analyze the file without executing it. An agent with shell or write tools could have done exactly what the malicious code wanted a real developer to do: execute it.
The defense-in-depth lesson is the one the author is most explicit about in the postmortem. He writes: "Reviewing the code with a read-only agent turned out more productive than reading it myself. The backdoor was dressed up as sloppy beginner code, but the agent flagged it in seconds." The point is not that an AI agent is the right tool for everyone. The point is that the AI agent's read-only toolset, combined with a throwaway execution environment, is the operational pattern that catches this attack class at the file-review layer rather than at the post-execution forensics layer. Reading the code with your own eyes, without the agent and without the throwaway, is the failure mode. The postmortem is explicit that on a "more tired or rushed day" the author could easily have run 'npm install' before thinking it through. The defense is the operational posture, not the cleverness of the reader.[1]
The defense is also the inverse of the new "AI tools as the new attack surface" thread that ran the same week. Developer Tech News reported on June 15, 2026 that an "AI agent" had breached the Fedora software supply chain, and Forbes ran "Autonomous Malware Is No Longer Theoretical" the same day. The same AI agent pattern that the author used defensively (read-only, on a throwaway, reviewing code) is the same AI agent pattern that an attacker can use offensively (autonomous, with write tools, on a real developer's machine). The defense and the attack are the same primitive, pointing in opposite directions. The two together are the most important privacy-and-security framing of the cycle.[7]
The Identity-Layer Problem: Borrowed Profiles Are the New Spam, and LinkedIn's Verification Has Not Caught Up
The postmortem is specific on the two impersonated identities. The first is the 39-commit attribution to a real full-stack engineer. The engineer confirmed to the author that he had never worked for the company, that he had been impersonated on GitHub before, that he had previously had a repo taken down over the impersonation, and that he was reporting the new repos too. The second is the recruiter's LinkedIn profile, which belonged to a real, well-known arts journalist. When the author stalled and told the "recruiter" that the project would not install, the journalist pivoted in real time to debating Node versions and pushed harder for the npm install. The pivot is the second tell, and the pivot is the part that any human reviewer can catch if they take the time to ask "does this person actually do this work."[1]
The identity-borrowing pattern is not new. The HN thread on the postmortem is dominated by it. One commenter (HN 48546294) writes: "LinkedIn offers no way for $company to disavow users who claim to work for $company. They will appear on the official company page as long as it's in their profile. We've had fake recruiters that claim to work for us running basically the same scam." The comment is the operational summary of the problem. LinkedIn's "I work at X" field is a self-attested string. There is no platform-level verification. The company can disavow in its own posts, but the disavowal does not strip the badge from the impersonating profile. The impersonator keeps the LinkedIn Premium icon, the relevant posts, and the company-page association.[2]
The product fix is employer-verified recruiter profiles by default, and the security community has been asking for the fix for years. The Five Eyes joint advisory of June 5, 2026 ("Chinese Spies Are Recruiting on LinkedIn") made the same point: the intelligence agencies on both sides of the Atlantic and Pacific have been watching the LinkedIn-recruiter-as-initial-access pattern for at least five years, and the platform's verification layer has not closed the gap. The roman.pt postmortem is the first 2026 example of the pattern executing the full chain (identity → distribution → auto-execute) to deliver working malware to a developer machine. The previous examples stopped at the recruiter DM or the GitHub impersonation. The npm 'prepare' trigger is what completes the chain.[8]
The State-Aligned Thread: This Looks Like the North Korean Developer-Targeting Pattern, and the Same Domain Was Used in March
The Hacker News ran a companion piece on June 15, 2026 at 19:32 UTC under the headline "North Korean Hackers Are Turning Developer Tools Into Malware Delivery Channels." The piece ties the LinkedIn backdoor to a pattern that includes the Shai-Hulud worm hitting Microsoft GitHub repos, the Arch Linux AUR 1,500-package incident, and the Slack video-embed E2EE exploit from the same week.[3] The HN commenters on the roman.pt postmortem independently reach the same conclusion. One commenter links to a "I was likely targeted by DPRK" blog post and notes the same email campaign pattern from earlier in 2026. The convergence of the structural evidence (state-aligned-developer targeting, public-repo impersonation, identity-layer compromise, auto-execute trigger) and the community signal (the HN thread, the prior Reddit r/openclaw March 2026 thread, the Forbes "Autonomous Malware" June 15 piece) is the strongest case yet that the LinkedIn backdoor is part of a state-aligned attack campaign rather than an isolated criminal op.[2]
The rest-icon-handler.store domain is the smoking-gun indicator. The HN commenters note that the same domain appears in a March 2026 Reddit r/openclaw post describing the same social-engineering pattern via LinkedIn. The same domain, the same LinkedIn-→-GitHub-→-npm chain, the same "check out the deprecated Node modules issue" framing across at least three months means the infrastructure has been continuously operational and continuously hitting developers. Three months is a long run for a malicious infrastructure domain. The persistence is itself the story.[9][4]
The Sonatype "Atomic Arch" piece of June 11, 2026 is the second parallel attack class. Sonatype documented attackers hijacking trusted AUR packages (Arch Linux's user repository) to deliver rootkit-like malware. The AUR is the Arch Linux analog of npm. The auto-execute primitive (a lifecycle hook that runs on install) is the same. The identity layer in the AUR case is the maintainer account rather than the recruiter DM, but the structural shape is identical. Three package ecosystems, three attacks, three months: npm, AUR, and the developer-targeted Slack E2EE exploit. The 2026 supply-chain attack consolidation is real, and the consolidation is the privacy story.[4]
The Takedown Pipeline Is Broken: GitHub and LinkedIn Have Not Removed the Code or the Profile
The single most important number in the postmortem is the one in the last paragraph. The author writes: "I reported the repo to GitHub and the recruiter to LinkedIn. So far nothing has changed and the code is still up."[1] The author is not the only person who has reported the infrastructure. The impersonated full-stack engineer had previously had a repo taken down for the same reason, but the new repo is still up. The HN thread on the postmortem has been live since June 15 evening UTC. The platform takedown pipeline for this attack class is currently measured in "still up" weeks, not hours.
The persistence of the delivery infrastructure is the second shareable hook in the cycle, and it is the structural problem that the Five Eyes joint advisory of June 5, 2026 was pointing at. The advisory noted that LinkedIn's verification pipeline is a primary risk surface for state-aligned targeting, and called on LinkedIn to ship employer-verified recruiter profiles by default. LinkedIn has not shipped the change. The roman.pt postmortem is the operational case for why the change is overdue.[8]
The GitHub side has the same problem. The malicious code is in a public repo. The commit history is forged. The impersonated engineer has reported the impersonation, and the previous repo was taken down, and the new repo is still up. The auto-execute trigger is the npm 'prepare' script, which any developer who runs 'npm install' on the repo will fire. Every hour the repo is up is an hour a developer can run 'npm install' and lose their machine. The takedown pipeline is the single biggest defensive gap in the cycle, and the gap is currently measured in "still up" days, not in "auto-mitigated" hours.
What It Means for You Today
Three groups are affected, and the consequences diverge.
If you are a developer who gets a recruiter DM with a GitHub link. The postmortem is unambiguous on the operational pattern. The postmortem says: "If you get a LinkedIn message asking you to review a repo, a bit of paranoia and good security hygiene never hurts."[1] The operational pattern is: (1) do not clone and run 'npm install' on your own machine, (2) spin up a throwaway VPS (Hetzner, DigitalOcean, Fly.io, any provider that lets you nuke the instance in a single command), (3) point a read-only code-review agent (or your own eyes, with the file open) at the repo, (4) look for URL fragments in any "test" file, (5) look for any lifecycle hook ('prepare', 'postinstall', 'preinstall') in 'package.json' that runs 'node' on a file that requires a "test" module, (6) check the commit author identity against the impersonated-engineer prior-incident list, and (7) check the recruiter's public profile for a non-technical cultural background pivoting to technical vocabulary in DMs. The check is 5 minutes. The "npm install" is 30 seconds. The "npm install" is the one that takes your machine.
If you run an open-source project that accepts outside contributions. The postmortem is also a case study in what the impersonation looks like from the defender's side. The 39 forged commits were attributed to a real engineer's name and email, with a commit history that looked plausible. The defense on the maintainer side is to enforce commit signing (GPG or SSH) on the project, to require CODEOWNERS review on the 'package.json' and any "test" file with lifecycle hooks, and to monitor the public list of impersonated-engineer accounts and refuse to accept commits attributed to any of them. The same operational pattern that catches the roman.pt-style attack catches the Axios-npm-style attack and the Bitwarden-CLI-style attack. The maintainer-side surface is the same surface at scale.[5][6]
If you run a platform (GitHub, LinkedIn, npm) that hosts any piece of this attack chain. The postmortem is the case for the takedown pipeline to move from "manual report, week-long response, code still up" to "auto-detect URL fragments in 'test' files, auto-flag 'prepare' lifecycle hooks that require non-test modules, auto-mitigate repos with the same rest-icon-handler.store domain across multiple accounts." The Five Eyes joint advisory of June 5, 2026 made the same call on the LinkedIn side. The roman.pt postmortem makes the same call on the GitHub and npm side. The fix is technically straightforward. The fix is organizationally hard because the fix crosses two platform companies. The fix is overdue because every hour the delivery infrastructure is up is an hour a developer can lose their machine.
The Bottom Line
Roman Imankulov's first-person postmortem at roman.pt on June 15, 2026 documents a clean three-step attack chain (LinkedIn identity, GitHub distribution, npm auto-execute) that the privacy and security community had not previously seen executed end-to-end with this much fidelity.[1] The postmortem landed at the top of the Hacker News front page on June 15-16, 2026, where it accumulated 712 points and 148 comments in the first hours.[2] The Hacker News companion piece on June 15, 2026 tied the attack to the state-aligned-developer-targeting pattern.[3] The Sonatype "Atomic Arch" piece of June 11, 2026 tied the attack to the AUR-auto-execute parallel class.[4]
The single most under-shared number in the cycle is the takedown-pipeline number. The malicious repo is still on GitHub. The recruiter profile is still on LinkedIn. The author reported both. The impersonated engineer has reported the same infrastructure pattern before. The platform takedown pipeline for this attack class is currently measured in "still up" weeks. Every hour the delivery infrastructure is up is an hour a developer can lose their machine.
Watch for four things over the next 7 days. First, the first public statement from GitHub or LinkedIn on the report Imankulov filed. Second, the first major-outlet identification of the threat actor behind the rest-icon-handler.store infrastructure. Third, the first peer-reviewed security analysis of the 'prepare'-script-as-attack-surface pattern across npm, PyPI, and RubyGems. Fourth, the first LinkedIn product change to employer-verified recruiter profiles as a default, the same product change Five Eyes called for on June 5, 2026. The first, second, and fourth are the platform-side responses. The third is the academic-side response. All four together would close the gap. None of them are public yet.
Sources
- Roman Imankulov, roman.pt: "A backdoor in a LinkedIn job offer" (June 15, 2026, primary source for the fake-recruiter LinkedIn pitch, the public GitHub repo, the 250-line 'app/test/index.js' file with the URL-fragment assembly to rest-icon-handler.store/icons/77, the npm 'prepare' lifecycle hook, the read-only AI agent detection on a throwaway Hetzner VPS, the 39-commit forged commit history attributed to an impersonated real full-stack engineer, the borrowed arts-journalist recruiter profile, the instant pivot to debating Node versions, and the 'so far nothing has changed' takedown-pipeline status)
- Hacker News: "A backdoor in a LinkedIn job offer" (HN 48546294, 712 points and 148 comments at scan, top of front page on June 15-16, 2026, the comment thread containing the LinkedIn-no-employer-disavow comment, the Raed667 comment linking the prior r/openclaw sighting of the rest-icon-handler.store domain, and the DPRK-framing comments from cluckindan, clemailacct1, and denysvitali)
- The Hacker News: "North Korean Hackers Are Turning Developer Tools Into Malware Delivery Channels" (June 15, 2026, 19:32 UTC, the state-aligned-developer-targeting framing and the consolidation of the 2026 developer-supply-chain incidents including the Shai-Hulud worm, the Arch Linux AUR 1,500-package incident, and the Slack video-embed E2EE exploit)
- Sonatype: "Atomic Arch npm Campaign Adds Malicious Dependency" (June 11, 2026, original AUR post-install-PKGBUILD attack write-up; the AUR package-manager auto-execute parallel attack class, the second ecosystem where the lifecycle-hook-as-attack-surface pattern is now operationally exploited)
- State of Surveillance: "North Korea Hijacked the Axios npm Package. Your App Might Be Compromised." (April 7, 2026, the prior npm-package-targeted supply-chain compromise in the same chain, with the GitHub-distribution and npm-auto-execute primitives already operational)
- State of Surveillance: "Bitwarden CLI Hacked for 90 Minutes. Malware Hunted Your AI Coding Tools." (April 26, 2026, the 90-minute Bitwarden CLI compromise, the AI-coding-tools-targeted supply-chain attack, and the read-only-posture defense at the developer side)
- Developer Tech News: "AI Agent Breaches Fedora Software Supply Chain" (June 15, 2026, 16:58 UTC, the AI-agent-as-offensive-attack-surface companion piece, the inverse of the read-only-defensive agent pattern in the roman.pt postmortem)
- State of Surveillance: "Five Eyes Issues Rare Joint Warning: Chinese Spies Are Recruiting on LinkedIn" (June 5, 2026, the prior rare-joint-advisory framing of the LinkedIn-recruiter-as-initial-access pattern, the product-fix call for employer-verified recruiter profiles)
- Reddit r/openclaw: "Someone tried to social engineer me via LinkedIn" (March 2026, the prior incident in the same chain, referenced by the HN comments as the prior sighting of the rest-icon-handler.store infrastructure)