Command Palette

Search for a command to run...

0
Blog
Next

Incident report: React CVE-2025-55182 (react2shell) miner breach

How the React CVE-2025-55182 window led to a systemf crypto miner on my server, and what it took to remove and rebuild.

Incident overview

I was still on the vulnerable React build when the react2shell advisory hit. Patching took a few hours. In that gap, someone used the SSR hydration bug to drop a systemf miner. I didn’t notice until days later, when CPU and RAM charts looked like a rollercoaster and a miner was squatting in /tmp.

Timeline

  • Day 0 — morning: still on the vulnerable React 19 build.
  • Day 0 — afternoon: Wiz advisory drops; I start patching, it takes hours.
  • Day 0 — evening: the exploit lands, writes /tmp/systemf/systemf, and starts mining.
  • Day 3: graphs show sustained high CPU/RAM; systemf is calling pool.hashvault.pro:443.
  • Day 3 — later: service pulled, egress blocked, forensics grabbed.

What I found

The giveaway was a systemf process running:

/tmp/systemf/systemf -o pool.hashvault.pro:443 --tls

It’s xmrig, pushing ~300% CPU, running as UID 1001 (not a real user), and living in /tmp. Definitely on the host, not inside Docker or Dokploy.

Looking for persistence

No cron jobs (root or user), no systemd services, no rc.local or shell profile hooks, and nothing odd in Docker containers or images. It behaved like a loader that kept recreating the binary in /tmp, not a full persistence setup.

Containment

I yanked the host out of rotation, blocked egress, grabbed memory plus /tmp and .next for forensics, killed the miner, and set /tmp/systemf and /tmp/systemf/systemf immutable. Then I rotated every secret and API key.

Quick checks

  • /tmp/systemf was empty after containment.
  • Docker containers and images were clean; nothing unexpected in Dokploy.
    So, host OS was hit; containers stayed clean.

Rebuild

  • Wiped the box and reinstalled from a trusted image.
  • Upgraded React to the patched release.
  • Rebuilt clean (no reused .next), confirmed no runtime writes to /tmp.
  • Deployed in a container with /tmp mounted noexec; installs via pnpm install --frozen-lockfile.
  • Added startup integrity checks for .next and node_modules.

Final status

Miner removed and blocked, containers clean, backups safe, host rebuilt from scratch.

Lessons

Patch framework releases fast. Sandbox SSR (noexec /tmp, read-only code, least privilege). Alert on new outbound destinations. Monitor .next, /tmp, and node_modules. Don’t “clean” an RCE’d host—rebuild it.