Setting Access-Control-Allow-Origin to * tells browsers that any website may make cross-origin requests to your API. For a truly public, unauthenticated endpoint that is fine. For anything that relies on the browser sending cookies or that returns data tied to a user, a wildcard origin combined with credentials is a real exposure, and browsers will even block the dangerous combination for you.
Why it's a problem
If your API authenticates with cookies and you reflect a permissive origin while allowing credentials, a malicious page the victim visits can make authenticated requests to your API and read the responses using the victim's session. The wildcard is safe only when the endpoint is genuinely public and carries no per-user data or credentials.
The pattern
// allows every site on the internet to call this API
app.use(cors({ origin: "*", credentials: true })); // browsers block this comboThe fix
const allowed = new Set([
"https://app.example.com",
"https://admin.example.com",
]);
app.use(cors({
origin: (origin, cb) => cb(null, !origin || allowed.has(origin)),
credentials: true,
}));Why AI tools write this
When an assistant is asked to 'fix the CORS error,' the wildcard is the change that makes the error disappear immediately, so it is the one that gets written. It resolves the symptom the developer reported without reasoning about which origins should actually be trusted, because that is a judgment call about the app, not the error.
The quick fix
- Replace the wildcard with an explicit allowlist of the origins you control.
- Never combine origin: '*' with credentials: true.
- Only leave a wildcard on endpoints that are fully public and return no user-specific data.
Common questions
Is Access-Control-Allow-Origin: * always dangerous?
Not for public endpoints that return non-sensitive data and require no credentials. The risk is specific to APIs that use cookies or Authorization headers for per-user data.
Can I use a wildcard with credentials: true?
No. Browsers block this combination outright. If you need credentialed cross-origin requests, you must specify an exact allowlisted origin, never a wildcard.
How do I allow multiple specific origins without a wildcard?
Use a Set or array of approved origins and a dynamic origin callback that checks whether the request Origin header is in that list, then passes the matching origin to the callback.