Last week I experienced one of the most eye-opening security incidents in my time building web apps.
My production Next.js application was actively targeted by attackers attempting remote code execution (RCE), and the root cause was a newly disclosed vulnerability in React Server Components.
This is a write-up of what happened, how I diagnosed the issue, how I patched it, and what steps I took to harden my infrastructure.
1) The First Signs: Suspicious Logs in My Container
Everything began when I noticed strange logs while checking my Docker containers:
/bin/sh: curl: not found
/base64 -d | bash
ping: bad address
cat: can't open '.env.production'
Attackers were:
- Attempting to download malicious scripts
- Trying to exfiltrate environment variables
- Dropping files into
/tmp - Running reconnaissance commands
- Injecting base64-encoded payloads
At this stage, nothing persisted on the filesystem, and no malicious binaries survived container restarts, which was a good sign.
Still, something was definitely trying to execute shell commands inside my app.
2) Investigating the Root Cause
My first instinct was to examine my own server-side code:
- I reviewed all route handlers
- Audited every Server Action
- Scanned the codebase for any
child_process.exec,spawn, or CLI wrappers.
None of my code executed shell commands, nothing even close.
This led to the next logical suspicion: a framework-level vulnerability, and that's exactly what it was.
The Culprit: CVE-2025-55182 (React2Shell)
It turns out my app was running a Next.js version that used a vulnerable build of React Server Components, specifically the versions affected by CVE-2025-55182 - React2Shell.
A critical, pre-authentication RCE caused by unsafe deserialization in React's RSC/Flight protocol.
With a single crafted HTTP request, an attacker could trigger arbitrary code execution inside the Node.js server, even with no custom API endpoints.
I tested the publicly available PoC against my running app…
And it worked.
Suddenly everything made sense.
3) Fixing the Vulnerability
The React team released patches, and Next.js provided an official tool to upgrade vulnerable packages.
To fix the issue, I ran:
npx fix-react2shell-next
This updated:
- React RSC internals
- Next.js internals depending on the vulnerable code path
I rebuilt and redeployed my app from clean Docker images.
Then I tested the PoC again: Exploit failed. Completely.
This was the moment I knew the issue was resolved.
Running npx fix-react2shell-next on an affected Next.js app - confirming active vulnerabilities and applying the official patch.
4) Hardening My Infrastructure (This Saved Me)
Even though the vulnerability existed, the attacker never gained persistence or escalated to the host. Why?
Because I had already hardened my Docker environment:
- Read-only root filesystem
-
/tmpmounted withnoexec - All Linux capabilities dropped
-
no-new-privilegesenabled - No
bash,curlinstalled inside the container - Isolated writable directories
- Nginx rate limiting and reverse-proxy filtering
These security layers prevented: file execution, script downloads, persistence installation, cron modifications, privilege escalation, writing outside isolated volumes.
In the end: the vulnerability allowed RCE, but the environment stopped it from becoming a full compromise.
5) Post-Incident Actions
Even after patching, I also:
- Rotated all environment secrets
- Re-deployed everything from clean images
- Validated no malicious files remained
- Reviewed logs to confirm attack attempts were blocked
Because as we often say: Security is not just about fixing one issue, it’s an ongoing process.
6) Key Takeaways for Developers
Here’s what I learned and what you should be doing too:
a. Patch fast
React2Shell was actively exploited in the wild. If your app uses Next.js + RSC, you must update.
b. Least privilege saves lives
A read-only root filesystem alone can break 80% of real-world attack chains.
c. Don’t rely on your own code being perfect
Framework vulnerabilities happen and attackers move fast.
d. Use multiple layers of defense
No single measure stopped this attack, together, they did.
e. Monitor everything
Logs revealed the attack before it was too late.
7) The Bottom Line
This experience was intense but deeply educational. I’m sharing this story only a few days after the attack, but incidents like this can happen to anyone, and every victim has their own story behind it.
It reinforced how important it is to stay up to date, harden your runtime environment, assume that vulnerabilities will happen, and prepare your infrastructure to handle them safely.
If even one person reading this patches their application or improves their security setup, then writing this was absolutely worth it.
References:

Top comments (0)