You shipped your app in a weekend. It works. It's beautiful. You're proud.
But did your AI assistant secure it?
Probably not. Here's why — and here's the 16-point checklist to fix it before you ship.
The Problem: AI Optimizes for Working Code
When you ask Cursor or Lovable to "add user authentication," it gives you working auth. What it doesn't give you:
- Rate limiting on the login endpoint
- Row Level Security on your database tables
- Secure session management
- Proper CORS configuration
AI tools are trained to produce code that compiles and runs. Security is almost never in the training objective. The result: 91.5% of AI-built apps have at least one security vulnerability (per GuardMint's audit of 200+ apps).
Martin Fowler's team at Thoughtworks said it best:
Here's everything you need to check — before and after you ship.
Pre-Launch: 8 Things to Check Before You Ship
1. 🔴 Scan for Exposed Secrets
What AI does: Hardcodes API keys, database URLs, and tokens directly in your code.
Check:
grep -r "sk-\|api_key\|password\|secret\|token\|eyJ" \
--include="*.js" --include="*.ts" --include="*.py" .
Fix: Move all secrets to environment variables (.env, never committed). Use a secrets scanner like trufflehog.
2. 🔴 Verify Row Level Security (RLS)
What AI does: Creates tables without RLS. In Supabase, RLS is off by default. 70% of Lovable apps ship this way.
Check:
SELECT tablename, rowsecurity
FROM pg_tables WHERE schemaname = 'public';
Fix:
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read own data" ON your_table
FOR SELECT USING (auth.uid() = user_id);
3. 🔴 Audit Service Account Permissions
What AI does: Creates service accounts with admin/owner roles because it's simpler.
Fix: Apply least-privilege. If a service only needs to read one bucket, don't give it full project access.
4. 🔴 Check Auth Guards on Every Route
What AI does: Creates API routes with zero authentication checks.
// AI happily creates unprotected routes:
app.get('/api/user-data', (req, res) => {
// No auth check! Anyone can hit this.
const data = await db.query('SELECT * FROM users');
res.json(data);
});
Fix: Add auth middleware to ALL protected routes. Never rely on frontend-only auth checks.
5. 🟡 Review Storage Bucket Permissions
What AI does: Makes buckets public "so images load without auth."
Fix: Make buckets private. Generate signed URLs for authenticated access.
6. 🟡 Run Dependency Vulnerability Scan
Check:
npm audit # or: pip audit, bundle audit
Fix: Update vulnerable packages. If no fix exists, consider alternatives.
7. 🟡 Check .env and .git Exposure
What AI does: May not add .env to .gitignore.
echo ".env*" >> .gitignore
git rm --cached .env
8. 🟡 Review CORS Configuration
What AI does: Sets CORS to allow all origins (*) for convenience.
// DON'T: cors({ origin: '*' })
// DO: cors({ origin: 'https://yourdomain.com' })
Post-Launch: 8 Things to Check After You're Live
9. 🔴 SSL/TLS Certificate Validity
Fix: Use Let's Encrypt (free) or your hosting provider's SSL. Enable auto-renewal.
10. 🔴 Security Headers
Scan your URL at securityheaders.com. Must-haves:
Strict-Transport-Security(HSTS)Content-Security-Policy(CSP)X-Frame-OptionsX-Content-Type-OptionsReferrer-Policy
11. 🔴 Exposed .env and .git on Live Server
Visit yourdomain.com/.env and yourdomain.com/.git/ — do they return anything?
Fix:
# Nginx
location ~ /\. { deny all; }
12. 🟡 Secrets in Production JS Bundles
Check: DevTools → Sources → search JS bundles for "api_key", "sk-", "eyJ".
Fix: Use server-side API routes as proxies. Never embed secrets in client-side code.
13. 🟡 Rate Limiting on Auth Endpoints
import rateLimit from 'express-rate-limit';
app.use('/api/auth/', rateLimit({
windowMs: 15 * 60 * 1000,
max: 10 // 10 attempts per 15 min
}));
14. 🟡 SQL Injection Prevention
// DANGEROUS:
db.query(`SELECT * FROM users WHERE id = ${userId}`)
// SAFE:
db.query('SELECT * FROM users WHERE id = $1', [userId])
15. 🟡 Content Security Policy
Start with a report-only policy, tighten gradually:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
16. 🟢 Breach Monitoring
Set up HaveIBeenPwned domain monitoring (free). Check periodically.
The One Thing That Makes All the Difference
Security isn't a one-time check. It's a practice. The best thing you can do is add a security context file to your AI coding tool:
# Security Rules for AI Assistant
- NEVER hardcode secrets, API keys, or tokens
- ALWAYS enable Row Level Security on database tables
- NEVER make storage buckets publicly accessible
- ALWAYS use least-privilege for service accounts
- ALWAYS add authentication checks to protected routes
- ALWAYS use parameterized queries (never string concatenation)
- ALWAYS add rate limiting to auth endpoints
Paste this into every project. Your AI literally can't suggest insecure defaults anymore.
Automate All 16 Checks
VibeSafe runs every check in this article automatically.
📁 Pre-Launch Audit ($39) — repo scan, plain-English report in 24h
🌐 Post-Launch Scan ($19) — live URL scan, trust badge
🛡️ Shield ($29) — auto-generated AI security context file
📦 Full Bundle ($49) — all three, best value