DEV Community

Cover image for 🚨 Critical Next.js Vulnerability: Server Hijacked by Crypto Miner
Manav Verma
Manav Verma

Posted on • Edited on

🚨 Critical Next.js Vulnerability: Server Hijacked by Crypto Miner

🚨 Critical Next.js Vulnerability: Server Hijacked by Crypto Miner

If you are running Next.js (especially App Router), stop what you are doing and check your servers. I just spent the last 24 hours fighting a nightmare scenario where 2-3 of my production apps were suddenly compromised.

Here is exactly what happened, how I found it, and how you can fix it.

The Symptoms: "Suddenly, Silence"

Everything was running smoothly until my server monitoring screamed.

  • CPU Spikes: Usage hit 100% and stayed there.
  • Server Shutdown: The load was so high the VM eventually crashed.
  • Filesystem Changes: I noticed immediate changes in my git staging areaβ€”files I didn't touch were modified.

The Analysis: What the Hacker Did

The attacker used a Remote Code Execution (RCE) vulnerability to gain entry and immediately set up shop to mine Monero (XMR).

1. Code Level Compromise

They didn't just run a script; they embedded themselves into my source code to ensure persistence.

  • Modified Configs: Malicious lines were injected into next.config.js, tailwind.config.js, and postcss.config.js.
  • Manifest Injection: A custom manifest file was added.
  • Git Staged Changes: I caught them red-handed via git statusβ€”yarn.lock and package.json were modified to pull malicious dependencies.

2. Machine Level Compromise

This was the scary part. They escalated out of the Node.js process:

  • System Services: They created systemd services with random hexadecimal names (e.g., a1b2c3d4.service) to restart the miner if I killed it.
  • Shell Poisoning: They added lines to my .bashrc and .profile so the miner would start whenever I logged in.

3. The Payload (xmrig)

They installed xmrig, a high-performance Monero miner. I found a config.json file dropped in the miner's directory configured to use max-threads-hint: 100 and huge-pages, which explains why the server was choking.


How I Cleaned It Up (Remediation Guide)

If you are infected, you need to act fast. Here is the cleanup process I used.

1. Stop the Bleeding
Immediately kill the miner processes. Note: The process might be named xmrig, but attackers often rename it to look like a system process.

# Force kill all processes matching "xmrig"
sudo pkill -9 -f xmrig
Enter fullscreen mode Exit fullscreen mode

Tip: Check top or htop for any other processes taking 80-90% CPU and kill them.

2. Remove Persistence (Systemd Services)
The attackers hid services with random hex names.

# List all running services and look for random hex strings
systemctl list-units --type=service --state=running

# Stop and disable suspicious services
sudo systemctl stop [service_name]
sudo systemctl disable [service_name]
sudo rm /etc/systemd/system/[service_name]
sudo systemctl daemon-reload
Enter fullscreen mode Exit fullscreen mode

3. Clean System Shells
Check your shell profiles (~/.bashrc, ~/.profile). Remove any lines that look like curl commands fetching scripts or exports you didn't add.

🏠 VITAL: Check for HOME Directory Hijacking

A sophisticated attacker may hijack your environment variables to break tools like NVM/Conda or redirect configuration files to a temporary directory (/tmp), where they can hide or run malware.

To see if this has happened to your $HOME variable, run these commands:

  1. Check the currently set variable:

    echo $HOME
    

    If this outputs /tmp or any path other than /home/yourusername, your environment is poisoned.

  2. Find the malicious override:
    You need to search the system-wide configuration files (where the attacker placed the reset command) for the incorrect path. Replace /tmp with the incorrect path found in step 1 if necessary:

    sudo grep -R 'HOME=/tmp' /etc
    

    The output will point you to the exact file (e.g., /etc/profile.d/env.sh). Edit that file (using sudo) and remove the line to restore your system's default behavior.

4. Clean the Codebase & Verify Configs
Resetting git is a good start, but you must manually verify the content of your config files.

# Reset local changes
git reset --hard HEAD
git clean -fd
Enter fullscreen mode Exit fullscreen mode

⚠️ Vital Step: Open your next.config.js, tailwind.config.js, and system files. Read them line-by-line. Attackers are getting better at obfuscating code.

  • Pro Tip: If you see a block of code in your config that looks suspicious or complex, copy and paste it into an AI tool (like ChatGPT or Gemini) and ask: "Is this code malicious? What does it do?" Don't take chances.

5. Rotate Secrets
Since they had RCE, assume they stole your .env file. Revoke and generate new database credentials and API keys immediately.


Final Step: Patch Immediately!

Cleaning the miner doesn't close the door. You must upgrade Next.js to the latest patched version to prevent them from walking right back in.

Please refer to the official Next.js security blog for the exact version numbers you need to target:
πŸ‘‰ Next.js Security Advisory: CVE-2025-66478

Update your dependencies accordingly:

npm install next@latest react@latest react-dom@latest
# or
yarn add next@latest react@latest react-dom@latest
Enter fullscreen mode Exit fullscreen mode

Deep Dive Analysis

For a detailed technical breakdown of how this "React2Shell" vulnerability works and how the attackers exploit it, read this report:
πŸ‘‰ Wiz.io: Critical Vulnerability in React (CVE-2025-55182)

Stay safe and check your logs!

NOTE: FOR SAFETY I PREFER RESET ALL OF YOUR CREDENTIALS AND MIGRATE TO NEW INSTANCE OR SERVER

Let me know in the comments what you think about this solution and how you are handling these security challenges in your own projects.

Top comments (0)