DEV Community

A LinkedIn Recruiter Sent Me Malware Disguised as a "Pre-Interview Code Review"

Vladimir Novick on May 04, 2026

A LinkedIn recruiter pitched me a remote "Software Engineer at a DEX" project this week. Reasonable comp range, tech stack squarely in my wheelhous...
Collapse
 
czep profile image
Scott Czepiel

Thanks for this write-up, and the warning to never let your guard down even if you suspect nothing. I have stopped using npm in my own projects in favor of pnpm which will not run postinstall scripts unless explicitly whitelisted. Do not ever trust npm install with code whose authors you cannot personally vouch for.

Collapse
 
circuit profile image
Rahul S

pnpm's onlyBuiltDependencies is solid for lifecycle scripts, but this specific attack has a nastier property — even with --ignore-scripts, if the developer runs node app/index.js to actually look at the project (which is the whole point of a "code review"), the payload fires. The install path is just one entry point; manual execution is another.

The deeper issue is that developers clone repos into environments where live credentials sit in process.env. Docker dev containers or nix develop shells with empty credential stores would limit blast radius to zero even if the malicious code does execute — it can only steal what's present at runtime. The attack steals process.env, so an environment with nothing in it gives up nothing.

I've started treating "review unknown code" as a separate workflow from "develop my own projects" — different shell, different env, no mounted credential files. Slight friction, but it makes this entire class of attack a no-op regardless of what the package manager does or doesn't run.

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer • Edited

It's becoming easier to fake job vacancies and impersonate coworkers or recruiters, so it's more important than ever to listen to our gut feelings, double check and dare to say no before someone cheats us in a desperate situation.

I wrote this comment also as a reminder to myself. Despite my professional experience, I got involved in a discussion that turned out a fake similar to your fake HR interview.

In my case, the fake bot didn't act as a recruiter, but as a customer, allegedly a founder of a new product. They produced a reason to prefer Slack over zoom and announced they'd proceed with a NDA and a VPS access to a preview to the backend of a "maintenance mode" placholder website. The chat felt like talking to AI, and forwarding it to Google Gemini together with their LinkedIn profile provided further red flags within seconds. The cover story didn't add up, while too many aspects were typical for a scam like that.

Collapse
 
peacebinflow profile image
PEACEBINFLOW

The detail about the prepare script camouflaging itself as a Create-React-App build pipeline is the part that'll stick with me. Not because the technique is technically sophisticated — it's actually pretty simple — but because it exploits something that isn't really a technical vulnerability at all. It exploits scanning habits.

Most of us have trained ourselves to skim package.json scripts with a specific pattern-matching lens: we look for things that feel off. A weird binary name, an obfuscated one-liner, a curl pipe to bash. But that nonsense react-scripts --openssl-legacy-provider build --kill-others string doesn't trigger the "off" detector because it's composed entirely of tokens that look like they belong there. It's visual static that blends into the expected noise of a modern JavaScript build chain. My brain sees "react-scripts," "build," some flags I half-recognize from a StackOverflow answer two years ago, and just moves on.

That's the part I find unsettling in a useful way. It suggests the defense isn't just "be more careful reading scripts" because the attack is specifically designed to pass through careful-enough reading. The real defense is the mechanical one you mentioned — --ignore-scripts as default behavior, not as a special precaution. I wonder how many of us have that flipped in our heads, where running scripts is the default and ignoring them is the paranoid exception.

Collapse
 
leob profile image
leob • Edited

"I wonder how many of us have that flipped in our heads, where running scripts is the default and ignoring them is the paranoid exception" - eh, the majority? Really useful warning, this article ...

Collapse
 
leob profile image
leob • Edited

That's insane! What would be the end goal of these North Korean hackers, apart from pleasing Kim Jong Un telling him that they duped a bunch of gullible "westerners"? ;-)

(joking there of course - I think it's VERY easy to fall for this, I wouldn't blame anyone for doing so - good to make people aware of this !!)

Collapse
 
txdesk profile image
TxDesk

The Google Doc as C2 is genuinely clever. Rotating the destination without touching the repo means every static IOC list is outdated the moment it's published. Same problem shows up in DeFi post-exploit response: after the Wasabi exploit last week, a phishing account called "Wascbi Profocol" posted fake revoke links in the same Discord threads where real users were asking for help. Different attack vector, identical structure: impersonate a trusted source, target people in a moment of vulnerability, exploit the gap between "this looks legitimate" and "this is legitimate."

The anti-analysis filtering (blocking Gitpod, Codespaces, Windows VS Code terminals) is the detail that stands out to me. The attacker specifically optimized against the environments security researchers use. That's not a script kiddie. That's someone who's been caught before and iterated.

Your "one precaution" section is the right framing. The equivalent in DeFi is: reading a contract on Etherscan is safe. Signing a transaction from a link in a Discord thread where you're panicking about an exploit is where you get drained. The risky step is always the moment you execute something from an unverified source under time pressure. Job hunting and post-exploit panic create the same vulnerability: urgency that overrides verification instincts.

Collapse
 
pvgomes profile image
Paulo Victor Leite Lima Gomes

OMG, this is an absurd by design... the C2-via-Google-Doc trick is interesting. Rotating the payload destination by editing a doc, with no repo commit and no blocked domain? That's genuinely clever operational security for a phishing campaign.

The Function.constructor indirection to dodge SAST is also worth flagging louder. A lot of teams rely on automated scans as a security blanket, and this shows how thin that blanket is against someone who spent five minutes thinking about keyword matching.

One thing I'd add for folks doing contract/freelance work: --ignore-scripts as a default install flag is great advice, but you can enforce it project-wide via .npmrc with ignore-scripts=true. Locks it in so you don't forget on a rushed install.

The "fake job" vector is particularly predatory right now with so many engineers on the market. I'm in that situation myself, actively job searching, and I've had a few suspicious recruiter approaches lately. The Calendly invite as a legitimacy signal is a nice touch on their part, just enough friction to feel real.

Also thanks for documenting this properly. sharing it.

Collapse
 
itskondrat profile image
Mykola Kondratiuk

seen this pattern. someone I know got hit with the same thing - GitHub repo, 'just review before the call.' the tell is always urgency plus a Calendly in the same message.

Collapse
 
ravindrank profile image
Ravindran K

This is valuable info!!

Collapse
 
https_gabe profile image
Gabriel

Article's too long 😐

Collapse
 
leob profile image
leob

You're joking? The article is just right - what's more, it's fantastic!