CORS Misconfiguration in Vibe-Coded Apps: Wildcard Origins Explained - VibeDoctor 
← All Articles 🔒 Security Vulnerabilities High

CORS Misconfiguration in Vibe-Coded Apps: Wildcard Origins Explained

Wildcard CORS origins let any website call your API. Learn how AI tools misconfigure Access-Control headers and how to fix them.

SEC-004

Quick Answer

A wildcard CORS origin (Access-Control-Allow-Origin: *) tells browsers that any website in the world may make cross-origin requests to your API. When combined with credentials, this creates a serious security hole. AI tools generate wildcard CORS headers by default because they eliminate friction during development - the problem is those defaults ship to production.

What CORS Actually Does

Cross-Origin Resource Sharing (CORS) is a browser security mechanism that restricts which origins can call your API from JavaScript running on a different domain. Without CORS headers, a script on evil.com cannot fetch data from yourapp.com/api/users - the browser blocks it. When you add Access-Control-Allow-Origin: *, you instruct the browser to lift that restriction for every origin on the internet.

The distinction that matters: CORS is enforced by browsers, not servers. Direct server-to-server requests, curl, and tools like Postman bypass CORS entirely. What CORS protects against is a malicious website convincing a logged-in user's browser to make API requests on their behalf - which is exactly the threat model for CSRF-style attacks on modern SPAs.

According to the OWASP Web Security Testing Guide, CORS misconfiguration is one of the most prevalent server-side misconfigurations in modern web applications. A 2023 analysis by the Cloud Security Alliance (CSA) found that CORS headers are misconfigured in more than 35% of surveyed web APIs, with wildcard origins being the most common error.

How AI Tools Generate Wildcard CORS

When you ask Cursor, Bolt, or Lovable to "add CORS support to my Express API," the generated code almost always looks like this:

// ❌ BAD - Wildcard CORS that allows any origin
const express = require('express');
const cors = require('cors');

const app = express();

// AI-generated: "allows all origins" - dangerous in production
app.use(cors());
// Equivalent to:
// app.use(cors({ origin: '*' }));

app.get('/api/user/profile', async (req, res) => {
  const userId = req.session.userId;
  const user = await db.user.findUnique({ where: { id: userId } });
  res.json(user);
});

Calling cors() with no arguments is equivalent to setting Access-Control-Allow-Origin: *. This passes preflight checks for simple requests from any domain. The danger is compounded if the API uses cookies or session tokens for authentication - any website can silently read data from your API on behalf of a logged-in user.

The Credentials Combination Makes It Critical

Wildcard CORS alone is bad. Wildcard CORS with Access-Control-Allow-Credentials: true is a critical vulnerability. Browsers normally refuse to send cookies or Authorization headers to a wildcard-origin endpoint, but AI tools sometimes generate both headers together when prompted to "fix CORS errors with authentication."

// ✅ GOOD - Explicit allowlist of permitted origins
const allowedOrigins = [
  'https://yourapp.com',
  'https://www.yourapp.com',
  process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : null,
].filter(Boolean);

app.use(cors({
  origin: (origin, callback) => {
    // Allow requests with no origin (curl, Postman, server-to-server)
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error(`CORS: origin ${origin} not allowed`));
    }
  },
  credentials: true,         // Only safe with an explicit origin list
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

In Next.js, CORS is configured per-route in the route.ts handler or globally via next.config.js headers. Vercel's Edge Config and middleware also provide a place to enforce origin allowlists at the network boundary before requests reach application code.

CORS Misconfiguration Patterns to Watch For

Misconfiguration Risk Fix
Access-Control-Allow-Origin: * Any site can read public API responses Explicit origin allowlist
Origin: * + credentials: true Browsers reject - but some older clients don't Never combine wildcard with credentials
Reflecting request Origin without validation Attacker controls the allowed origin dynamically Validate against explicit allowlist before reflecting
Null origin allowed Sandboxed iframes and data: URIs bypass restriction Remove null from allowlist entirely
Subdomain wildcard (*.yourapp.com) Any subdomain including XSS-vulnerable ones List specific subdomains explicitly

CORS in Supabase and Vercel Deployments

Supabase's hosted API already has its own CORS configuration, but when you add a Next.js or Express backend layer in front of Supabase - a common Bolt and Lovable architecture - that layer needs its own CORS policy. The Supabase client configuration on the frontend does not protect the middleware layer.

Vercel deployments support CORS header configuration in vercel.json. If you add a wildcard header there, it overrides any application-level CORS logic. Always audit your vercel.json headers block when deploying to Vercel. A common AI-generated pattern is:

// ❌ BAD - vercel.json wildcard that bypasses app-level CORS
{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [{ "key": "Access-Control-Allow-Origin", "value": "*" }]
    }
  ]
}

This single configuration change undoes any application-level origin validation across every API route in the project.

How to Find CORS Misconfigurations

A targeted search covers most cases. Look for cors() called without arguments, Access-Control-Allow-Origin set to a string literal "*", and any place where the incoming Origin header is reflected directly back without validation. In Next.js, check both next.config.js headers and individual route.ts files for response header assignments.

Tools like VibeDoctor (vibedoctor.io) automatically scan your codebase for wildcard CORS origins and flag specific file paths and line numbers. Free to sign up.

FAQ

Does wildcard CORS affect non-browser clients?

No. CORS is enforced by browsers only. Command-line tools like curl, server-to-server HTTP calls, and API clients like Postman ignore CORS headers entirely. The risk is exclusively about what a malicious website running in a victim's browser can do on their behalf.

Is wildcard CORS acceptable for public, read-only APIs?

Potentially, for truly public data that carries no user-specific information and requires no credentials. A public weather API or exchange rate feed can reasonably use a wildcard. The problem is that AI tools apply wildcard CORS to all routes including authenticated ones. Scope it deliberately rather than globally.

How does CORS interact with CSRF tokens?

They address different threat vectors. CORS controls cross-origin reads; CSRF tokens prevent cross-origin state-changing requests (writes). A properly configured CORS allowlist reduces the attack surface for CSRF, but it is not a substitute for CSRF protection on state-changing endpoints. Both should be in place.

What happens when I set credentials: true with a wildcard origin?

Modern browsers will reject the response with an error: "The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'." So the combination technically fails in compliant browsers - but older clients and non-standard runtimes may not enforce this, and the configuration intent is still wrong.

Does Supabase handle CORS for me?

Supabase's hosted PostgREST API manages its own CORS settings in the Supabase dashboard under API settings. You can add your domain to the allowed origins list there. However, any custom Edge Functions or API routes you write in your own backend still need their own CORS configuration - Supabase does not apply its settings to your application code.

Scan your codebase for this issue - free

VibeDoctor checks for SEC-004 and 128 other issues across 15 diagnostic areas.

SCAN MY APP →
← Back to all articles View all 129+ checks →