DEV Community

Kunsang Moktan
Kunsang Moktan

Posted on

Lessons Learned from the React2Shell Vulnerability (December 3, 2025)

On December 3, 2025, the React2Shell vulnerability was disclosed, exposing a serious remote code execution risk in certain React and Next.js setups. Unfortunately, this wasn’t just a headline for me—I experienced it firsthand on a client’s production server.

This post documents what happened, how the compromise was detected, and the most important lessons I learned as a developer.


The Incident

One of my client’s servers was running Next.js 16, which was affected by the vulnerability.

When I SSH’d into the server to deploy routine changes, I immediately noticed something was wrong:

  • node commands were failing unexpectedly
  • Deployment scripts wouldn’t execute
  • The server felt unusually slow

Checking system resources revealed the real issue.


What I Found

  • CPU usage was constantly above 100%
  • A suspicious process named xmirg was consuming ~106% CPU
  • Several unauthorized .sh files and a ZIP archive appeared in the project’s root directory

Attempts to kill the xmirg process were unsuccessful—it restarted automatically every time.

After deeper inspection, I discovered the malware had registered itself as a system service:

system.update.update.service
Enter fullscreen mode Exit fullscreen mode

The name was deliberately chosen to resemble a legitimate system update service, making it easy to overlook.

At this point, it was clear that:

  • The server had been fully compromised
  • It had been turned into a cryptocurrency mining machine
  • Application performance had degraded significantly

Containment & Resolution

Fortunately, the cloud service provider detected the malicious activity and temporarily limited the server’s CPU usage.

However, because the compromise occurred at the system level:

  • Cleaning the server was not safe
  • Trust in the system was irreversibly lost

The only correct action was to delete the server entirely and provision a new one from scratch.


Key Lessons Learned

1. Never Deploy Applications as the Root User

This was the most critical mistake.

The application was deployed and running with root privileges, which allowed the attacker to:

  • Install system-level services
  • Execute arbitrary shell scripts
  • Persist even after killing processes

Best practice:

  • Create a dedicated non-root user for deployments
  • Grant only the minimum permissions required
  • Use sudo explicitly when necessary

This alone can significantly limit the impact of an RCE vulnerability.


2. Firewalls Alone Are Not Enough

The attack did not bypass the firewall—it came through HTTPS (port 443).

This highlights an important truth:

If your application layer is vulnerable, network-level protection is not sufficient.

Security must include:

  • Dependency monitoring
  • Timely patching
  • Least-privilege execution
  • Runtime behavior monitoring

Final Thoughts

Vulnerabilities like React2Shell are a reminder that:

  • Modern frameworks are powerful—but not immune
  • One misconfiguration can turn a production server into a liability
  • Server hardening is just as important as secure code

This incident changed how I approach:

  • Deployment permissions
  • Server access control
  • Incident response

Top comments (1)

Collapse
 
grenishrai profile image
Grenish rai

Everyone learns from the mistake! Switch to Tanstack 😂