Skip to content

Why AI Generates CORS `origin: "*"` and Is It Safe for Production?

I found CORS wildcard configurations in almost every AI-generated Express or Fastify backend I’ve reviewed. The pattern is consistent: cors({ origin: "*" }) sitting in production code, quietly creating security vulnerabilities that rarely cause visible problems until someone exploits them.

The Problem: CORS Wildcards in AI-Generated Code

Ask any AI assistant to create a backend API, and you’ll likely get something like this:

server.js
const express = require('express');
const cors = require('cors');
const app = express();
// This works in development but is dangerous in production
app.use(cors({ origin: "*" }));
app.get('/api/users', (req, res) => {
res.json({ users: ['alice', 'bob'] });
});
app.listen(3000);

This configuration “just works” when your frontend runs on port 5173 and your backend on port 3000. No CORS errors. No debugging. The AI solved the immediate problem and moved on.

Why AI Defaults to Permissive CORS

AI code assistants prioritize getting you unstuck. When you ask for a backend that “works,” the AI optimizes for:

  1. Development friction reduction - Wildcard CORS eliminates the most common development error
  2. Minimal context requirements - No need to ask about your frontend URL
  3. Immediate success signal - The code runs without errors on first try

The AI doesn’t know you’re building for production. It doesn’t know your security requirements. It picks the path of least resistance.

A Reddit developer put it well: “Almost every AI-generated Express/Fastify backend I’ve scanned has cors({ origin: "*" }) or cors({ origin: true }). I think a lot of people don’t even realize it’s still in there because it never causes a visible problem.”

What CORS Origin Wildcard Actually Does

CORS (Cross-Origin Resource Sharing) is a browser security mechanism. When your frontend at https://app.example.com makes a request to your API at https://api.example.com, the browser checks if the API allows cross-origin requests.

With origin: "*", your API tells browsers: “Any website can read responses from this endpoint.”

HTTP Response Headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type

This means https://malicious-site.com can make requests to your API and read the responses through the victim’s browser.

Security Risks in Production

Data Exfiltration

If your API returns sensitive user data, any website can access it:

attacker-site.js
// This runs on https://evil.com
fetch('https://your-api.example.com/api/user/profile', {
credentials: 'include' // Includes cookies for authenticated requests
})
.then(res => res.json())
.then(data => {
// Attacker now has your user's profile data
sendToAttackerServer(data);
});

When a logged-in user visits the attacker’s site while your origin: "*" is active, their browser happily sends the request with their session cookie, and the response is readable by the attacker’s JavaScript.

CSRF Amplification

While CORS doesn’t enable CSRF directly (CSRF works without reading responses), wildcard CORS makes certain attacks more dangerous:

amplified-csrf.js
// Attacker can now read the response to verify attack success
fetch('https://your-api.example.com/api/account/delete', {
method: 'POST',
credentials: 'include',
body: JSON.stringify({ confirm: true })
})
.then(res => res.json())
.then(result => {
if (result.success) {
// Attacker confirms the deletion worked
notifyAttacker();
}
});

Credential Exposure with Wildcards

A critical mistake I’ve seen: combining credentials with wildcards:

vulnerable-credentials.js
// This is a SECURITY ERROR in most browsers
app.use(cors({
origin: "*",
credentials: true // This combination is rejected by browsers
}));

Browsers reject Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true. But the HTTP response still contains your sensitive data - the browser just blocks JavaScript access. Network-level attackers (or certain exploits) can still read it.

When Wildcard Is Acceptable vs Never Safe

Wildcard IS Acceptable For:

  • Public APIs with no authentication and intentionally public data
  • Development environments (never deploy to production)
  • Static asset CDNs serving images, fonts, or public files
acceptable-wildcard.js
// Acceptable for truly public, read-only data
app.get('/api/public/health', cors({ origin: "*" }), (req, res) => {
res.json({ status: 'ok', timestamp: Date.now() });
});

Wildcard Is NEVER Safe For:

  • Authenticated endpoints - Any route requiring session/cookie/JWT
  • User-specific data - Profile info, private messages, account settings
  • Write operations - POST, PUT, DELETE endpoints
  • Internal APIs - Services not meant for public consumption
  • Any production deployment without explicit security review

Secure Configuration Options

Static Whitelist

The simplest approach for known frontend origins:

static-whitelist.js
const cors = require('cors');
const allowedOrigins = [
'https://app.example.com',
'https://staging.example.com',
'http://localhost:5173' // Development only
];
app.use(cors({
origin: allowedOrigins,
credentials: true
}));

Dynamic Validation

For multi-tenant or dynamic subdomain scenarios:

dynamic-cors.js
const cors = require('cors');
app.use(cors({
origin: (origin, callback) => {
// Allow requests with no origin (mobile apps, curl)
if (!origin) return callback(null, true);
// Check against allowed patterns
const allowedPatterns = [
/^https:\/\/[a-z-]+\.example\.com$/, // *.example.com
/^http:\/\/localhost:\d+$/ // localhost any port (dev only)
];
const isAllowed = allowedPatterns.some(pattern => pattern.test(origin));
if (isAllowed) {
callback(null, true);
} else {
callback(new Error('CORS policy violation'));
}
},
credentials: true
}));

Environment-Based Configuration

Keep development flexibility while enforcing production security:

env-cors.js
const cors = require('cors');
const corsOptions = {
credentials: true,
origin: process.env.NODE_ENV === 'production'
? process.env.ALLOWED_ORIGINS.split(',')
: true // Allow all in development
};
app.use(cors(corsOptions));
.env.production
NODE_ENV=production
ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com

Fastify Equivalent

fastify-cors.js
const fastify = require('fastify')();
await fastify.register(require('@fastify/cors'), {
origin: process.env.NODE_ENV === 'production'
? process.env.ALLOWED_ORIGINS.split(',')
: true,
credentials: true
});

Production Security Checklist

Before deploying any API with CORS:

  • Audit all AI-generated CORS configurations
  • Replace origin: "*" with explicit origin list
  • Verify credentials: true only used with specific origins (never wildcards)
  • Test from an unauthorized origin (response should be blocked)
  • Review cookie settings: SameSite, Secure, HttpOnly flags
  • Add CORS-related security headers (see below)
  • Remove development origins from production whitelist
security-headers.js
app.use((req, res, next) => {
// Additional security headers
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
// Strict CSP for API responses
res.setHeader('Content-Security-Policy', "default-src 'none'");
next();
});

Summary

AI-generated origin: "*" works in development but creates production vulnerabilities. The wildcard exposes your API to:

  1. Cross-site data exfiltration - Any website can read your API responses
  2. Amplified CSRF attacks - Attackers can verify attack success
  3. Compliance violations - GDPR, HIPAA, SOC2 require access controls

The fix is straightforward: replace wildcards with explicit origin whitelists. Use environment variables to maintain development flexibility while enforcing production security. Review any AI-generated backend code before it reaches production - the CORS misconfiguration might be invisible until it’s exploited.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments