r/VibeCodeDevs • u/Just-Money-4241 • 11h ago
If you're vibe coding on top of a freelancer's codebase, read this before your next prompt
I picked up a new client's React Native app to help them ship on Android. Previous dev was an Upwork freelancer. 110 commits. Six months of real work. Clean looking codebase. Exactly the kind of project you'd clone, open in Cursor or VS Code, and start prompting on top of.
I asked Claude Code what it would take to get this on the Play Store. During that assessment it flagged the ESLint config file. Looked totally normal. Ten lines. Standard Expo boilerplate.
Except after the closing bracket on line 10, hidden behind 300 spaces on the same line, was an obfuscated remote code execution loader.
Every time ESLint ran — every time you saved a file, every time your editor auto-linted, every time CI ran — the loader executed. It fetched encrypted payloads from blockchain transactions, decrypted them, and ran whatever code the attacker had deployed that day. No servers involved. No domains. The command and control infrastructure is the Tron and Binance Smart Chain blockchains. Untakeable.
The attacker updated the payload 25 times over 12 months. Per-victim campaign identifiers in the code. This wasn't a one-off. The wallet was active 10 months before this client was even targeted. Estimated 10 to 30 or more Upwork clients could have this same loader sitting in their projects right now.
Why this matters if you vibe code:
You're not reading the codebase line by line. That's the whole point. You're prompting, generating, shipping. But when you clone a repo or inherit a project, you're trusting every file in it. And config files are the last thing anyone looks at.
eslint.config.js is not a config file. It's executable JavaScript. So is babel.config.js. So is metro.config.js. So is next.config.js. So is vite.config.ts. They all run code. They're all attack surface. And none of them show up in your prompts or your AI-generated diffs.
This payload was invisible in a normal code review. It was invisible in git diffs unless you scrolled horizontally past 300 characters. It was invisible to every linter and formatter. It was caught because an AI tool happened to dump the raw file contents during an unrelated task.
What you should do:
- If you've inherited or cloned a codebase from anyone — a freelancer, an agency, a previous team — check your config files. Open them in a terminal with
cat -Aorxxdand look for anything after what appears to be the last line. - Before you start vibe coding on top of a new project, ask your AI tool to audit the config files specifically. "Read every config file in this project and flag anything unusual."
- If you hired a JavaScript or React Native freelancer through Upwork, check your
eslint.config.jsright now. The attacker's GitHub handle isgarrycha. The payload uses this exact pattern — whitespace padding after the closing bracket on the same line.
The full reverse engineering breakdown with wallet addresses, decryption keys, and a monitoring script is posted on r/cybersecurity if you want the technical details.
110 commits of real work. One line in a config file. That's all it takes.

