I Found a Cryptominer in My Client's Production Cluster. Claude Code Found the Attacker.
A New Year's security incident, a CVSS 10.0 vulnerability, and an hour-long investigation that should have taken days.
New Year’s Day. Coffee in hand. Ready to ease back into work.
Then I saw the logs.
2026-01-02T06:34:27 GET xmrig-6.24.0-linux-static-x64.tar.gz
2026-01-02T06:34:30 GET http://37.32.6.33:7979/m
2026-01-02T06:34:30 spawn /opt/systemf/m ENOENTxmrig. In production. Someone was mining Monero on my client’s Kubernetes cluster.
The horror.
The Investigation
I had a few hundred megabytes of JSON logs and approximately zero patience for manually correlating timestamps. So I did what any reasonable person would do: I asked Claude Code to analyze the logs and figure out what triggered the miner download.
Within seconds, it built a timeline:
Time Event
06:34:26. Normal request to /onboarding
06:34:27. xmrig downloaded from GitHub
06:34:30. Secondary payload from sketchy IP
06:34:57. Container OOMKilled
The cryptominer was so resource-hungry it consumed 2GB of memory in 30 seconds and crashed the container. Ironic. The attacker’s greed saved us from a prolonged compromise.
But how did they get in?
Chasing Red Herrings
Claude Code’s first suspect: a low-version npm package called device-unique-keygen. Added by a developer whose email matched the package maintainer. Classic supply chain attack pattern.
I got excited. Maybe too excited.
Claude Code fetched the GitHub repo, analyzed the source code, checked for postinstall scripts, looked for obfuscated code, searched for eval() calls.
Nothing. The package was clean. Just a browser fingerprinting library. Boring. Legitimate.
We moved on.
No malicious init containers. No sidecars. No .ashrc shenanigans. The Dockerfile was clean. The pod spec was clean.
Everything was clean except someone was definitely mining crypto on our infrastructure.
The Actual Answer
Claude Code ran npm audit on the codebase.
critical │ Next.js is vulnerable to RCE in React flight protocol
Package │ next
Patched │ >=15.3.6
Your ver │ 15.3.4
CVSS │ 10.0CVSS 10. The maximum possible score. The “your house is actively on fire” of security ratings.
The app was running Next.js 15.3.4. A publicly disclosed RCE vulnerability. No authentication required. An attacker could run arbitrary commands on the server by sending a crafted request.
That’s exactly what happened. They sent a request, ran wget twice, downloaded the miner, and started extracting crypto value from compute cycles they weren’t paying for.
The container’s memory limit stopped them. A $20/month Kubernetes resource limit prevented what could have been ongoing theft.
What Claude Code Actually Did
I want to be clear about what happened here. I didn’t single-handedly unravel a sophisticated attack. I didn’t manually correlate log timestamps or reverse-engineer obfuscated npm packages.
I said “check these logs” and Claude Code:
Built a timeline from JSON log entries
Identified the malware artifacts and C2 server
Traced git blame to find who added suspicious packages
Fetched and analyzed source code from GitHub
Ruled out attack vectors one by one
Found the actual vulnerability via npm audit
Correlated the OOMKill timing with the attack
Suggested remediation and forensic preservation steps
The entire investigation took under an hour. Not because I’m fast. Because Claude Code is.
The Fix
pnpm update next@^15.3.6One command. That’s the remediation for a CVSS 10.0 vulnerability.
We also orphaned the compromised pods for forensic analysis, rotated secrets, and added proper security contexts to prevent future wget adventures.
The Lesson
Two things saved us:
Centralized logging (couldn’t investigate without the logs)
Memory limits (the attacker’s miner killed itself)
One thing would have prevented this entirely: running npm audit before deployment.
The attacker exploited a vulnerability that was publicly disclosed and patched. We just hadn’t updated yet.
Godspeed with your own dependency updates.
My Medium friends can read this over there as well.



