← Back to VibeScan
HighSecurity Finding

Wildcard CORS Policy on API Routes

VibeScan detected an Access-Control-Allow-Origin: * header on your API routes. This allows any website on the internet to make requests to your API using your users' credentials — without them knowing.

What CORS actually controls

Cross-Origin Resource Sharing (CORS) determines which external websites are allowed to make requests to your API from a browser. When you set it to *, you're telling the browser: “any website is allowed to call my API.”

Wildcard (dangerous)
Access-Control-Allow-Origin: *
Specific origin (safe)
Access-Control-Allow-Origin:
  https://myapp.com

How attackers exploit wildcard CORS

The attack is called Cross-Site Request Forgery (CSRF). Here's how it works in practice:

  1. An attacker builds a malicious page at evil.com with hidden JavaScript.
  2. They trick your logged-in user into visiting evil.com (phishing email, social post, etc.).
  3. The JavaScript on evil.com silently calls your API (e.g., POST /api/transfer-funds) using the user's active session cookies.
  4. Because your API allows * origins, the browser completes the request — and your user's account performs the action without their knowledge.

Important nuance: The wildcard is most dangerous when combined with cookie-based auth or when your API accepts credentials. Even without cookies, it still exposes any unauthenticated data your API returns.

How to fix it

1

Replace * with your specific domain

Set Access-Control-Allow-Origin to exactly your production domain. If you need multiple origins, check the request's Origin header against an allowlist.

// Next.js API route (App Router)
export async function GET(request: Request) {
  const origin = request.headers.get('origin')
  const allowedOrigins = ['https://myapp.com', 'https://www.myapp.com']
  
  const headers: Record<string, string> = {}
  if (origin && allowedOrigins.includes(origin)) {
    headers['Access-Control-Allow-Origin'] = origin
  }
  
  return Response.json({ data: '...' }, { headers })
}
2

Set it globally in next.config.js

Rather than setting CORS on each route, configure it once in your Next.js config to apply across all API routes.

// next.config.js
const nextConfig = {
  async headers() {
    return [{
      source: '/api/:path*',
      headers: [{
        key: 'Access-Control-Allow-Origin',
        value: 'https://www.myapp.com', // your domain
      }],
    }]
  },
}
3

Add CSRF protection for state-changing routes

For POST/PUT/DELETE endpoints, add a CSRF token check in addition to fixing CORS. Libraries like csrf-csrf make this straightforward.

Fix prompt for Lovable / Bolt / Cursor

“VibeScan found a wildcard CORS policy (Access-Control-Allow-Origin: *) on my API routes. Please fix this by replacing the wildcard with my specific domain in next.config.js headers config. The allowed origin should be https://www.myapp.com (replace with my actual domain). Also add CSRF protection to any state-changing POST/PUT/DELETE API routes using the csrf-csrf library.”

Check your app for CORS issues

VibeScan checks CORS headers on every API route alongside 10 other security checks — free, in under 60 seconds.

Scan my app free →