Traffic to firgun.win briefly 302'd to a malicious Arweave link because a stray container had claimed port 3000. We rebuilt the app, pruned stale containers, and tightened post-deploy port checks.
What happened
Users hitting firgun.win were briefly redirected to an Arweave link pointing to an unfamiliar IP. Our nginx config looked correct; the problem came from whatever was serving port 3000 upstream.
Investigation
curl -I http://127.0.0.1:3000returned a 302 to the Arweave URL, so the redirect originated from the process on port 3000, not nginx.docker psshowed the expected stock-picker web-app container was running, with no rogue container bound to port 3000.- Because nginx simply proxied to port 3000, traffic flowed through the legitimate web-app container, which was emitting the malicious redirect.
What we did to fix it
-
Rebuilt and recreated the web-app to replace the rogue listener:
docker compose up -d --build --force-recreate web-appThis immediately removed the redirect.
-
Pruned stale containers and build cache to clear leftover artifacts:
docker system prune -f -
Upgraded frontend dependencies (Next.js, React,
eslint-config-next) to current versions for security coverage. -
Verified port ownership and responses:
docker ps --filter publish=3000 curl -I http://127.0.0.1:3000 -
Checked nginx and logs to confirm the correct app was serving after the rebuild.
What actually went wrong (root cause)
The legitimate web-app container was returning the malicious 302. nginx dutifully proxied to it. The redirect source was the running web-app itself, which was vulnerable due to running React 19.1.0 (see React2Shell vulnerability section below).
The React 19.1.0 Vulnerability (React2Shell)
React 19.1.0 is severely vulnerable and was a primary factor in this incident. This version is affected by the React2Shell (CVE-2025-55182) vulnerability, a critical flaw with a CVSS 10.0 rating disclosed in December 2025. It allows unauthenticated attackers to execute code on your server by sending a single malicious HTTP request.
Why React 19.1.0 is Dangerous
- Insecure Deserialization: The vulnerability exists in how React Server Components (RSC) process “Flight” protocol data. Attackers can inject payloads that overwrite prototype methods, leading to Remote Code Execution (RCE).
- Default Vulnerability: The flaw is present in the default setup of apps using React 19.x - no specific misconfiguration is needed.
- Active Targeting: Botnets are actively scanning for React 19.1.0 to deploy cryptominers and redirect traffic to malicious sites (like the Arweave link we observed).
How to avoid this in the future
-
Recreate on deploys: Use
docker compose up -d --build --force-recreate web-appso the current image owns the port. -
Clean up regularly:
docker system prune -fto remove unused containers/images and prevent stale listeners. -
Port checks after deploys:
docker ps --filter publish=3000curl -I http://127.0.0.1:3000
-
No Docker API exposure: Confirm nothing is listening on
2375/2376:sudo ss -lntp | grep -E '2375|2376' -
Stay patched: Keep Next.js/React current; run
npm audit(or your package manager’s audit) and apply security updates promptly. React 19.1.0’s critical React2Shell vulnerability (CVE-2025-55182) shows how important timely updates are. -
Optional hardening: Use read-only filesystems and
tmpfsfor app containers when compatible, and add a simple health check/alert for unexpected 3xx to unknown domains.
Q&A
Did nginx cause the redirect?
No. nginx proxied correctly to port 3000; the running web-app container on that port emitted the 302.
Was this due to a rogue container?
docker ps showed only the expected web-app container on 3000. The redirect came from that container’s app, not from a separate rogue container.
How did React 19.1.0 factor in?
The affected site was running React 19.1.0, which is vulnerable to React2Shell (CVE-2025-55182). That made it possible for the app to be hijacked and return malicious redirects.
How can we detect this faster next time?
Add a post-deploy check that curls the upstream port and alerts on unexpected 3xx/4xx/5xx to unknown domains. Pair it with docker ps --filter publish=3000 to confirm port ownership.
Did traffic hit the malicious target?
We saw brief redirects, so some requests likely reached the Arweave URL. No evidence of data exfiltration; impact was redirect-only.
Why didn’t docker ps surface anything odd?
Because the legitimate container was the one misbehaving. Recreate on deploy to ensure the current image owns the port and hasn’t been tampered with.
Takeaway
The redirect came from the legitimate web-app container. Rebuilding the web-app and tightening post-deploy checks resolved it and reduces recurrence risk.
FAQ
- How could a legitimate container start serving malicious redirects?
- The container image or runtime was likely compromised, possibly through a dependency vulnerability or build-time injection. The container looked normal in `docker ps` but had malicious code listening on port 3000.
- Why didn't nginx catch this malicious behavior?
- Nginx was correctly configured as a reverse proxy. It simply forwarded requests to port 3000 and returned whatever response the upstream container sent—including the 302 redirect. Nginx doesn't inspect response content by default.
- Could this happen with any port, not just 3000?
- Yes. Any port that nginx proxies to could be hijacked if the upstream container is compromised. The key is monitoring upstream responses and securing your container build pipeline.
- How can we detect this faster next time?
- Implement automated health checks that verify expected response content, not just HTTP status codes. Also monitor for unexpected redirects and set up alerts when upstream responses change suddenly.
Welcome to The infinite monkey theorem
Somewhere a monkey just typed Shakespeare in TypeScript. Be the first to read the masterpieces (and the hilarious misfires) landing on the blog.

