Security Glossary

Cross-Origin Resource Sharing (CORS)

CORS is a browser security mechanism that controls which external domains can make requests to your API by using HTTP headers to relax the same-origin policy selectively.

Understanding Cross-Origin Resource Sharing (CORS)

By default, browsers block web pages from making requests to domains other than their own — this is the same-origin policy. CORS provides a controlled way to relax this restriction. When a frontend at app.example.com needs to call an API at api.example.com, the API must include CORS headers (like Access-Control-Allow-Origin) telling the browser that cross-origin requests from the frontend are permitted.

For simple requests (GET, POST with standard content types), the browser sends the request directly and checks the response headers. For complex requests (custom headers, PUT/DELETE methods, non-standard content types), the browser sends a preflight OPTIONS request first, and only proceeds if the server's response allows it. Misconfigured CORS that blocks preflight responses is one of the most common causes of mysterious frontend API failures.

The most dangerous CORS misconfiguration is setting Access-Control-Allow-Origin to * (wildcard) combined with Access-Control-Allow-Credentials: true. This combination is actually rejected by browsers, but developers sometimes work around it by dynamically reflecting the request's Origin header — which effectively allows any website to make authenticated requests to your API, enabling data theft.

Proper CORS configuration involves whitelisting specific trusted origins, only allowing necessary HTTP methods and headers, setting appropriate max-age for preflight caching, and understanding that CORS is a browser-enforced mechanism — it does not protect against direct API calls from scripts or tools like curl.

Why This Matters for Vibe-Coded Apps

AI-generated API configurations almost universally set CORS to allow all origins (*) because it is the fastest way to get a frontend and backend talking to each other. While this works in development, deploying with wildcard CORS means any website can call your API. For public read-only APIs this may be acceptable, but for APIs that handle user data or perform mutations, it is a security gap.

When an AI generates your API server configuration (Express, NestJS, FastAPI), check the CORS middleware settings before deploying. Replace wildcard origins with your actual frontend domain(s) and ensure credentials mode is configured correctly if you use cookie-based authentication.

Real-World Examples

BitBucket CORS Misconfiguration

A CORS misconfiguration in BitBucket's API allowed any website to make authenticated requests and access private repository data. The vulnerability stemmed from reflecting the Origin header without validation, effectively bypassing the same-origin policy for all authenticated users.

CORS Misconfig in Financial APIs

Multiple financial service providers were found reflecting arbitrary Origin headers in their CORS responses while allowing credentials. This allowed attackers to build websites that silently read account balances, transaction histories, and personal information from authenticated users who visited the malicious page.

Internal Network CORS Exploitation

Attackers used CORS misconfigurations on public-facing applications to pivot into internal network services. By making the victim's browser proxy requests to internal APIs that trusted the public application's origin, they accessed admin panels and internal data not exposed to the internet.

Frequently Asked Questions

Why is Access-Control-Allow-Origin: * not always dangerous?

Wildcard CORS only allows unauthenticated cross-origin requests. Browsers refuse to combine * with credentials: true, so cookies and authorization headers are not sent. For genuinely public APIs that serve public data (CDNs, open datasets, public REST APIs), wildcard CORS is appropriate. It becomes dangerous when developers work around the credential restriction by dynamically reflecting origins, or when the API should not be public.

What is a CORS preflight request?

A preflight is an OPTIONS request the browser sends before the actual request when the request uses non-standard headers, methods like PUT or DELETE, or non-standard content types. The preflight checks whether the server permits the actual request. If the server does not respond correctly to the OPTIONS request (with proper Access-Control-Allow-Methods and Access-Control-Allow-Headers), the browser blocks the real request. This is a common source of confusion during development.

Does CORS protect my API from unauthorized access?

No. CORS is a browser-only mechanism. It prevents other websites from making requests through a user's browser, but it does not protect against server-to-server requests, curl commands, or API clients like Postman. CORS should be considered a complement to authentication, not a replacement. Your API must still validate authentication tokens and authorize requests independently.

How do I handle CORS with multiple allowed origins?

The Access-Control-Allow-Origin header only accepts a single value or *. To support multiple origins, your server must read the incoming Origin header, check it against an allowlist, and if it matches, echo that specific origin back in the response header. Most CORS middleware libraries (Express cors, NestJS CORS, Django CORS Headers) handle this automatically when you provide an array of allowed origins.

Is Your App Protected?

VAS automatically scans for vulnerabilities related to cross-origin resource sharing (cors) and provides detailed remediation guidance. Our scanner targets issues common in AI-generated applications.

Scans from $5, results in minutes. Get actionable fixes tailored to your stack.

Get Starter Scan