Security & Auth
Secrets & Keys
The Vibe Coding Security Crisis
39 million secrets were leaked on GitHub in 2024 (GitHub report). 45% of AI-generated code contains security vulnerabilities. 1 in 5 vibe-coded apps has serious security vulnerabilities or configuration errors (Wiz Research).
How Secrets Leak
- Committed
.envfiles: The #1 source of leaked secrets. - Client-side exposure:
NEXT_PUBLIC_andVITE_prefixes bundle secrets into browser-visible JavaScript. - AI chat context: Pasting API keys into AI prompts can potentially leak them to third parties.
- Hardcoded in source: AI often writes
const API_KEY = "sk-..."directly into code. - Git history:
git rm .envremoves the file but the key remains in commit history forever.
Real-World Cost
$89K AWS Bill
A developer committed an AWS key to GitHub. Automated scanners find exposed keys in under a minute on average, then spin up cryptomining instances globally.
LLMjacking: $46K-$100K/day
Attackers steal exposed API keys (OpenAI, Anthropic) to run their own LLM workloads. You pay the bill.
72K Images Exposed (Tea App)
Including 13,000 government IDs. Cause: Firebase defaults left wide open because vibe coders didn't configure access rules.
The .env Setup (Do This First)
# .gitignore (MUST include these)
.env
.env.local
.env.production
.env*.local
# .env.example (commit this template)
DATABASE_URL=
STRIPE_SECRET_KEY=
OPENAI_API_KEY=
# Never commit actual values
Build-Time Validation
Use @t3-oss/env-nextjs to validate environment variables at build time. If a required secret is missing, the build fails instead of deploying a broken app.
Secret Scanning Tools
TruffleHog
800+ secret detectors. Verifies if leaked secrets are still live. Scans git history, not just current files.
RecommendedGitleaks
Fast secret scanning built for CI/CD pipelines (runs quickly in GitHub Actions).
SpeedGitHub Secret Scanning
Free for public repos. Push protection blocks commits containing known secret patterns before they hit GitHub.
FreeHow to Rotate Leaked Keys
Revoke Immediately: Go to dashboard (AWS, OpenAI) and delete the key. Every minute it's live, bots are using it.
Rotate: Generate a new key. Update .env.local and deployment vars (Vercel/Railway).
Clean History: Use BFG Repo-Cleaner to remove the file from git history. git rm isn't enough.
Scan: Run TruffleHog against the full repo to verify no other secrets exist in history.
API Key Rotation Schedule
PCI DSS 4.0 requires regular key rotation. Set calendar reminders.
Production Keys
90 days
Stripe, OpenAI, database credentials
Development Keys
6 months
Test API keys, staging DB passwords
Team Member Departure
Immediate
Rotate every key the departing member had access to
Suspected Compromise
Immediate
Revoke first, investigate second, generate new keys third
Blast Radius Containment
Limit damage when (not if) something goes wrong.
OpenAI
Use prepaid billing. Set hard usage limits. When credits hit zero, API stops. No surprise bills.
AWS
Set budget at $10. Alert at 80%. Use Service Control Policies to prevent launching expensive resources.
Stripe
Monitor dashboard daily for unusual charges and potential fraud patterns.
All Keys
Least privilege per environment. Dev keys should have minimal permissions. Never use production keys locally. Rotate every 90 days.
Auth & IDOR
Authentication vs. Authorization
Authentication is "Who are you?". Authorization is "What can you do?". AI almost always implements Auth (Login) but forgets Authorization (Permissions), leading to IDOR.
Auth Provider Comparison
| Provider | Free Tier | Paid | Notes |
|---|---|---|---|
| Clerk | 50K MRU | $25/mo + $0.02/MRU | Best UX. Beautiful drop-in components |
| Supabase Auth | 50K MAU | 100K MAU on Pro | Deeply integrated with Supabase DB. Best value |
| NextAuth/Auth.js | Free (open source) | Self-hosted | Single maintainer risk. Complex session handling |
| Lucia | Free (open source) | Self-hosted | Deprecated March 2025. Do not use for new projects |
| Auth0 | 25K MAU | Expensive at scale | Enterprise-grade. Parent company Okta disclosed 2022-2023 breaches (Okta said the Auth0 production service was not affected) |
CVE-2025-29927: One Header Bypassed All Auth
A CVSS 9.1 vulnerability in Next.js allowed a single HTTP header (x-middleware-subrequest) to bypass all middleware-based auth checks. Any site relying only on middleware for authentication was wide open. Lesson: Always verify authentication at the data retrieval layer (API route handlers, server actions), not just middleware.
IDOR (Insecure Direct Object Reference)
One of the most frequently reported vulnerability classes on bug bounty platforms, and the most common exploit in vibe-coded apps.
Vulnerable
/api/user?id=123Attacker changes ID to 124 and sees another user's data.
Secure
/api/me/profileBackend derives ID from the session token. User can't manipulate it.
IDOR Test (30 Seconds)
- 1.Log in as User A. Open DevTools Network tab.
- 2.Find an API request that includes a user ID or resource ID.
- 3.Copy the URL. Change the ID to a different number.
- 4.Paste it in a new browser tab. If you see another user's data, your app has IDOR.
Authorization Middleware Pattern
Wrap all protected API routes with a reusable auth check. Never rely on client-side checks alone.
Client-Side Only (Insecure)
// User can edit JS to bypass this!
if (user.role !== "admin")
return <div>Access denied</div>;
Server-Side Middleware (Secure)
// Reusable auth wrapper
export function withAuth(handler) {
return async (req) => {
const session = await getSession();
if (!session) return 401;
req.user = session.user;
return handler(req);
};
}
Common AI-generated auth mistakes: Missing RLS in Supabase, client-side only checks, no email verification, weak password requirements (accepts "123456"), exposed API routes without middleware, and session tokens in localStorage (vulnerable to XSS).
Row Level Security (Supabase)
83% of exposed Supabase databases involve RLS misconfigurations.
170 Lovable Apps Exposed (CVE-2025-48757)
Security researchers found 170 apps built with Lovable that had missing or misconfigured RLS policies, exposing user data. Lovable's default project setup left RLS disabled.
Common Mistakes
- Enabling RLS but creating no policies (blocks all access, so you disable it)
- Using the
service_rolekey in frontend code (bypasses all RLS) - Writing
USING (true)policies that allow all access - Forgetting RLS on new tables (disabled by default)
Correct Pattern
ALTER TABLE profiles
ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users read own data"
ON profiles FOR SELECT
USING (auth.uid() = user_id);
Quick Supabase RLS Test
Run this from a terminal without logging in: curl "https://your-project.supabase.co/rest/v1/profiles" -H "apikey: YOUR_ANON_KEY". If you see user data, RLS is broken.
Input Validation with Zod
Never trust the client. Validate everything on the server.
// Server-side validation schema
const UserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100).transform(
(val) => val.replace(/[<>]/g, '') // Sanitize HTML
),
password: z.string()
.min(8, "Password must be at least 8 characters")
.regex(/[A-Z]/, "Needs uppercase")
.regex(/[0-9]/, "Needs number"),
};
// Always use safeParse, never parse (which throws)
const result = UserSchema.safeParse(req.body);
if (!result.success) {}
return res.status(400).json({errors: result.error.flatten()});
};
// result.data is now fully typed and validated
const user = result.data;
// URL validation
z.string().url()
// Enum values
z.enum(["free", "pro", "enterprise"])
// Optional with default
z.string().optional().default("user")
// Age range
z.number().int().min(13).max(120)
Validate Env Vars at Build Time
Use @t3-oss/env-nextjs with Zod schemas to catch missing Stripe keys or database URLs at build time instead of discovering them in production.
XSS Prevention
Use .transform() to strip HTML tags from all text inputs before storing.
SQL Injection
ORMs like Prisma auto-parameterize queries. Never concatenate user input into SQL strings.
Rate Limiting
Add rate limiting to login, signup, and password reset. Use @upstash/ratelimit with Redis.
SQL Injection: Bad vs. Good
// DANGEROUS: Raw SQL concatenation
const query = `SELECT * FROM users
WHERE email = '${email}'`;
// Attacker input: ' OR '1'='1
// Returns ALL users!
// SAFE: Parameterized query
const query = `SELECT * FROM users
WHERE email = $1`;
await db.query(query, [email]);
// SAFE: Prisma (auto-parameterized)
await prisma.user.findUnique({where:
{email}});
XSS Prevention in React
// DANGEROUS: Never do this
<div dangerouslySetInnerHTML={
{__html: userInput}}
/>
// SAFE: If you must render HTML, sanitize first
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={
{__html: DOMPurify.sanitize(userInput)}}
/>
React auto-escapes text content by default. XSS only becomes a risk when you use dangerouslySetInnerHTML or inject content via href="javascript:..." attributes.
CSRF note: Most modern frameworks (Next.js, SvelteKit) handle CSRF protection automatically via same-site cookies and origin checking. Verify your framework's docs.
File Upload Security
File uploads are a common attack vector. Never trust the file extension or client-side MIME type.
const FileSchema = z.object({
file: z.instanceof(File)
.refine(f => f.size <= 5_000_000,
"Max file size is 5MB")
.refine(f =>
["image/jpeg", "image/png"].includes(f.type),
"Only JPEG and PNG allowed")
});
// Verify MIME by reading file bytes
import {fileTypeFromBuffer}from 'file-type';
const type = await fileTypeFromBuffer(buffer);
if (!type || !ALLOWED.includes(type.mime))
throw new Error("Invalid file type");
For virus scanning, consider ClamAV (self-hosted), Cloudflare R2 (built-in scanning), or AWS S3 with Macie.
Server-Side Proxy Pattern
Never call external APIs directly from client-side code with exposed keys. Instead, create a server-side API route that makes the call. Your frontend calls your server route, which calls the external API with the secret key. The key never reaches the browser. This is the proper alternative to prefixing secrets with NEXT_PUBLIC_ just to make something work.
Pre-Launch Security Checklist
.env files are in .gitignoreNEXT_PUBLIC_ or VITE_ prefixesEvidence, Breaches & OWASP
Compliance Quick Reference
For detailed coverage of GDPR enforcement, CCPA fines, COPPA, cookie consent, AI copyright, open-source licensing, and accessibility lawsuits, see the Legal and Compliance tab. That page includes deletion cascade patterns, privacy policy generators, data storage guidelines, and jurisdiction-specific cookie consent rules.
Academic Evidence on AI Code Security
Peer-reviewed research consistently shows AI makes developers overconfident while producing less secure code.
Stanford Study (ACM CCS 2023)
47 participants using OpenAI Codex wrote significantly less secure code in 4 of 5 tasks compared to the control group. Critically, participants with AI access were more likely to believe their code was secure than those without AI.
Perry et al., arXiv 2211.03622Pearce et al. (IEEE S&P 2022)
Tested 1,692 Copilot-generated programs across 89 scenarios. 40% were vulnerable. Python code was 39% vulnerable. C code hit 50%.
1,692 programs testedVeracode 2025 GenAI Report
Tested 100+ LLMs across 80 coding tasks. 45% of AI-generated code failed basic security tests. Failure rates by language: Java 72%, C# 45%, JavaScript 43%, Python 38%. XSS had an 86% failure rate.
Most comprehensive study to dateCloud Security Alliance
62% of AI-generated code samples contained design flaws or known vulnerabilities.
Apiiro Research (2025)
Across Fortune 50 enterprises using AI coding tools, Apiiro measured over 10,000 new security findings per month, a tenfold spike in just six months.
Copilot Code Review Study
Copilot's code review feature frequently fails to detect critical vulnerabilities like SQL injection, XSS, and insecure deserialization. Its feedback primarily targets low-severity style issues.
arXiv 2509.13650The Overconfidence Trap
AI makes developers overconfident about security while simultaneously producing less secure code. One Stanford participant admitted: "When it came to learning JavaScript (which I'm VERY weak at) I trusted the machine to know more than I did." This false confidence is the most dangerous outcome.
Real Security Breaches in Vibe-Coded Apps
These aren't hypotheticals. Every one of these happened in production.
Enrichlead (March 2025)
Founder built entire SaaS with Cursor AI, zero hand-written code. Within days: API keys maxed, subscriptions bypassed, random database writes. No auth, no rate limiting, no input validation. Shut down permanently.
Moltbook (2025)
Misconfigured Supabase database with full read/write access exposed 1.5 million API tokens, 35,000 email addresses, and private messages. Founder said he had vibe-coded the platform.
Tea Dating App (2025)
Women-only safety platform exposed 72,000 images including 13,000 government IDs through unconfigured Firebase defaults. A second leak followed exposing user chats.
Base44 Authentication Bypass
A logic flaw let attackers bypass authentication (including SSO) for private app environments, potentially reaching sensitive corporate data. Wiz disclosed it shortly after Wix acquired Base44; Wix patched it within 24 hours.
Escape.tech: Scanning 5,600 Vibe-Coded Apps
Escape.tech scanned 5,600+ publicly available vibe-coded applications and found:
- 2,000+ high-impact security vulnerabilities
- 400+ exposed secrets (API keys, database URLs)
- 175 instances of exposed PII, including medical records and bank account details
- 170 Lovable-built apps with missing or misconfigured RLS (see RLS section above)
Wiz independently found that about 20% of vibe-coded apps have serious vulnerabilities or configuration errors.
OWASP Top 10:2025 Mapped to AI-Generated Code
Based on analysis of 175,000+ CVE records and data across roughly 515,000 applications. Each item below shows how it specifically manifests in vibe-coded apps.
A01: Broken Access Control
AI skips authorization checks entirely. IDOR vulnerabilities everywhere. SSRF (previously A10 in 2021) is now rolled into A01 in OWASP's 2025 list. The Lovable CVE-2025-48757 exposed 170+ sites through exactly this failure.
A02: Security Misconfiguration
Default configs shipped to production, exposed debug endpoints, Supabase and Firebase deployed without security rules. Promoted from A05 in 2021, it is now the #1 real-world vibe-coding issue.
A03: Software Supply Chain Failures
Broader successor to 2021's "Vulnerable & Outdated Components." AI suggests deprecated or vulnerable packages; "slopsquatting" (hallucinated package names) appears in roughly 5% of commercial AI code samples, creating supply chain attack vectors.
A04: Cryptographic Failures
Hardcoded JWT secrets (research has documented widespread reuse of placeholder values like "supersecretkey" in vibe-coded apps), weak hashing algorithms like MD5 and SHA1, and missing encryption at rest. Was A02 in 2021.
A05: Injection
AI uses string concatenation instead of parameterized queries, producing SQL injection flaws. XSS has an 86% failure rate per Veracode 2025. Was A03 in 2021.
A06: Insecure Design
No threat modeling, happy-path only. AI satisfies the immediate prompt without broader security context or defense-in-depth architecture. Was A04 in 2021.
A07: Authentication Failures
Missing rate limiting on login, weak password policies, JWT with "none" algorithm acceptance, using HMAC when RSA was requested. Position unchanged from 2021.
A08: Software or Data Integrity Failures
No webhook signature verification. Invisible Unicode character attacks in AI-suggested code. No dependency integrity checks. Position unchanged from 2021.
A09: Logging & Alerting Failures
No audit trail at all, or the opposite: logging sensitive data like passwords and tokens. 88% of AI code fails log injection protection per Veracode 2025. Renamed in 2025 from "Security Logging and Monitoring Failures," with greater emphasis on alerting.
A10: Mishandling of Exceptional Conditions NEW in 2025
Minimal or wrong error handling that leaks stack traces, opens denial-of-service paths, or fails open instead of failing closed. AI commonly omits try/catch around third-party calls or returns raw exception text to clients. (SSRF, the 2021 A10, has moved into A01 as a sub-category.)
JWT Mistakes AI Consistently Makes
Research from MadAppGang, Semgrep, 42Crunch, and HackerOne documents eight recurring patterns in AI-generated JWT code.
Wrong Algorithm
AI generates HS256 (symmetric) when RS256 (asymmetric) is needed for distributed systems. HMAC is less secure here because verification doesn't require a private key.
Deprecated Library
AI suggests jsonwebtoken v8 or Go's dgrijalva/jwt-go (deprecated since 2021 with known critical CVEs). Use jose instead.
Hardcoded Secrets
Semgrep found hardcoded secrets as the most basic JWT mistake. Scans repeatedly turn up apps shipping with placeholder JWT secrets like "supersecretkey" committed straight into source.
"none" Algorithm Not Blocked
AI code often doesn't validate the alg header claim. Attackers set alg: "none" to bypass signature verification entirely, creating unsigned tokens.
Missing Claims Validation
AI decodes tokens without verifying exp (expiration), iss (issuer), and aud (audience) claims. Expired or misrouted tokens are accepted.
Algorithm Confusion Attacks
AI code accepts both symmetric and asymmetric algorithms. Attackers exploit RS256 to HS256 confusion, using the public key as an HMAC secret to forge tokens.
Token in localStorage
AI stores JWT in localStorage, which any script on the page can read (XSS vulnerability). Tokens belong in httpOnly cookies that JavaScript can't access.
Missing Token Lifecycle
No refresh token rotation, no token revocation, no expiration dates. Once issued, tokens work forever, even after password changes or account compromise.
Secrets Management by the Numbers
GitHub and GitGuardian data from 2024 reports. The problem is getting worse, not better.
39M
Secrets leaked on GitHub in 2024
Detected by GitHub secret scanning
23.8M
New, never-before-seen hardcoded secrets
25% year-over-year increase
70%
Of secrets leaked in 2022 still active in 2024
Persistent "zombie leak" attack surfaces
6.4%
Copilot secret leakage rate
Public repos using Copilot specifically
$4.88M
Global average cost of a data breach
IBM 2024 Cost of a Data Breach Report
4 min
Time for bots to find exposed AWS keys
Automated scanners monitor every GitHub push
Key pattern: 1 in 10 commit authors has leaked a secret, 7 of every 1,000 commits expose at least one, and over 90% of leaked secrets remain valid 5 days after exposure.
Rate Limiting Tools and Thresholds
AI-generated code almost never includes rate limiting. Add it to every endpoint that accepts user input or costs money.
express-rate-limit
Free, ~18M weekly npm downloads. The standard for Node.js/Express apps.
Gotcha: Behind proxies (Heroku, AWS, Cloudflare), you must set app.set('trust proxy', 1) or the limiter becomes global, blocking everyone. AI never includes this.
@upstash/ratelimit
SDK is free. Underlying Redis costs $0.20 per 100K requests. Supports sliding window, fixed window, and token bucket algorithms.
Best choice for Next.js + Vercel serverless deployments.
ServerlessCloudflare Rate Limiting
Free on all plans since October 2022 (1 rule on free, 10 on Pro at $20/mo). Edge-based blocking before requests hit your origin.
No code changes needed. Automatic bot protection included.
No Code| Endpoint | Limit | Scope |
|---|---|---|
| Login | 5 attempts / 15 min | Per IP |
| Signup | 3 / hour | Per IP |
| Password Reset | 3 / hour | Per email |
| API Endpoints | 100 / minute | Per user |
| File Uploads | 10 / hour | Per user |
| Expensive Ops (AI calls) | 5 / minute | Per user |
Audit Workflows & Prompts
Multi-LLM Security Audit Approach
Different AI models catch different vulnerability types. Using one model for security review leaves blind spots.
Semgrep Study (September 2025)
Claude Code and OpenAI Codex were tested on 11 large open-source Python apps. Their strengths were starkly complementary: Claude found 22% of IDOR bugs but only 5% of SQL injection. Codex found 47% of path traversal bugs but 0% of IDOR. Neither alone caught everything.
Security by Default Rates
Security varies enormously by model and prompt. Veracode tested 100+ models across 80 coding tasks and found only about 55% of generated code passed basic security checks, so roughly 45% shipped a known flaw. Per-model rates shift with every release, and explicit security prompting measurably improves results, so don't assume any single model is safe by default. This variation is exactly why multi-model review is essential.
LLMBugScanner (Georgia Tech, Dec 2025)
A framework that fine-tunes multiple LLMs and combines them with ensemble voting for smart-contract vulnerability detection. Its weighted ensemble outperformed every individual model, reinforcing that no single model is best across all vulnerability types.
Self-Reflection Prompting
Databricks found that asking a model to review its own output for security issues catches vulnerabilities the initial generation missed. Claude replaced a pickle serialization RCE it had originally generated with JSON after reviewing its own code.
"Review this code ONLY for security vulnerabilities. Assume a hostile internet environment. Check for: exposed secrets, missing auth, injection, XSS, IDOR, missing rate limiting, insecure defaults. For each finding, state the vulnerability type, the specific line(s), and the fix."
Generate code with your primary model (Claude, GPT, Cursor).
Run the security review prompt above with a different model than the one that wrote the code.
Combine findings from both models. Models have complementary blind spots, so the union of their findings is more comprehensive than either alone.
Layer static analysis (Semgrep, SonarQube) on top of AI review. Deterministic tools catch pattern-based vulnerabilities that all models miss.
Copy-Paste Security Audit Prompts
Three structured audit prompts. Run each with a different AI model than the one that wrote your code.