Vibe Coding Security

8 Security Mistakes Cursor AI Makes (And How to Fix Them)

SecuriSky TeamApril 9, 20269 min read

Why Cursor AI Has Security Blind Spots

Cursor AI is trained on millions of code examples — including millions of code examples with security flaws.

It optimizes for working code, not secure code. The result is a set of predictable, repeated security mistakes.

After scanning thousands of apps built with Cursor, we've identified the 8 most common patterns.

Mistake #1: Service Role Key Used Everywhere

What Cursor does: Uses SUPABASE_SERVICE_ROLE_KEY for all database operations because it "just works" — no permission errors. Why it's dangerous: Bypasses all RLS policies. Any server-side bug becomes a full data breach. Fix: Use the user's JWT token to create a scoped Supabase client:
const supabase = createClient(url, anonKey, {
  global: { headers: { Authorization: Bearer ${userToken} } }

});

Mistake #2: CORS Set to Wildcard With Credentials

What Cursor does: Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true Why it's dangerous: Any website can make authenticated requests on behalf of your users. Fix: Restrict origins to your actual domains:
app.add_middleware(CORSMiddleware, allow_origins=["https://yourapp.com"])

Mistake #3: No Rate Limiting on Auth Endpoints

What Cursor does: Creates /api/auth/login with no rate limiting. Why it's dangerous: Brute force attacks, credential stuffing, account enumeration. Fix: Use Upstash Redis-based rate limiting or implement token bucket on the endpoint.

Mistake #4: User-Controlled IDs in Database Queries

What Cursor does:
const { data } = await supabase
  .from('documents')
  .select('*')
  .eq('id', params.id); // ← user-controlled, no ownership check

Why it's dangerous: IDOR (Insecure Direct Object Reference) — users can fetch other users' data by guessing IDs. Fix: Always add .eq('user_id', session.user.id) to every query.

Mistake #5: Storing Secrets in localStorage

What Cursor does: localStorage.setItem('token', accessToken) Why it's dangerous: XSS attacks can steal all localStorage data. JWT tokens in localStorage = session hijacking. Fix: Use httpOnly cookies for sensitive tokens. Let your auth provider (Firebase, Supabase) handle token storage.

Mistake #6: SQL-Like Injection in Supabase RPC

What Cursor does:
const { data } = await supabase.rpc('search_posts', {
  query: userInput // ← unvalidated user input

});

Why it's dangerous: Even though Supabase uses parameterized queries by default, custom RPC functions often don't. Fix: Validate and sanitize all inputs before passing to RPC functions. Use Zod schemas.

Mistake #7: Sensitive Data in URL Parameters

What Cursor does: /dashboard?userId=123&token=abc — puts sensitive identifiers in URLs. Why it's dangerous: URLs appear in server logs, browser history, and Referrer headers. Tokens in URLs get leaked. Fix: Use POST body or Authorization headers for sensitive data. Never put tokens in URLs.

Mistake #8: Missing Input Validation on File Uploads

What Cursor does: Accepts file uploads without validation:
const file = req.file;

await storage.upload(file); // ← no type/size check

Why it's dangerous: Malicious file uploads, path traversal, storage cost attacks. Fix:
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp'];

if (!ALLOWED_TYPES.includes(file.mimetype)) throw new Error('Invalid file type');

if (file.size > 5 1024 1024) throw new Error('File too large');

How to Automatically Detect These

SecuriSky's scanner detects all 8 of these patterns automatically — including the ones hiding in your JavaScript bundles and Supabase configuration.

Run a free quick-scan at securisky.dev/scan/public, then sign up for the full 18-surface audit.

8 Security Mistakes Cursor AI Makes in 2025 (With Fixes) — SecuriSky Blog