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:
-
nodecommands 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
xmirgwas consuming ~106% CPU - Several unauthorized
.shfiles 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
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
sudoexplicitly 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)
Everyone learns from the mistake! Switch to Tanstack 😂