Skip to main content

CORS - Cross-Origin Resource Sharing

About 2 min read

CORS (Cross-Origin Resource Sharing) is an access-control mechanism for when a browser sends a request to a server on a different origin (a combination of domain, port, and protocol). It was published as a W3C recommendation in 2014 and is now implemented by all major browsers. Today, as the architecture of running a web application's frontend and backend on separate domains has become common, correctly understanding and configuring CORS is an essential skill for web developers. It is also a security mechanism closely related to CSRF and XSS.

Relationship with the Same-Origin Policy (SOP)

To understand CORS, you first need to know the Same-Origin Policy (SOP). The SOP is a browser security model introduced in Netscape Navigator 2.0 in 1995, with the constraint that "a script loaded from one origin cannot access resources of another origin."

Components of an origin:
https://example.com:443/path
Scheme: httpsHost: example.comPort: 443
Only when all three match is it the "same origin." The path is irrelevant.
https://example.com/page1 → https://example.com/page2 (same)
https://example.com → http://example.com (scheme differs)
https://example.com → https://api.example.com (host differs)
https://example.com → https://example.com:8080 (port differs)

Without the SOP, attacks such as a malicious site calling a bank site's API to obtain a user's account information would easily succeed. CORS is a mechanism for safely relaxing this SOP constraint. By having the server explicitly declare "I allow requests from this origin," it enables legitimate cross-origin communication.

How the Preflight Request (OPTIONS) Works

Before sending a cross-origin request that meets certain conditions, the browser sends a "preflight request" using the OPTIONS method. This is a mechanism for checking with the server in advance: "Will you accept this request?"

Browser sends OPTIONSServer returns permission headersBrowser confirms permissionSend the actual requestServer returns the response

The conditions that trigger a preflight include the use of the PUT / DELETE / PATCH methods, Content-Type: application/json and other custom headers, and sending credentials (cookies). A GET request with no custom headers is treated as a "simple request," and the preflight is skipped.

Key CORS Response Headers

HeaderRoleCaveats
Access-Control-Allow-OriginSpecifies the allowed originThe wildcard (*) cannot be used together with credentialed requests
Access-Control-Allow-MethodsLists the allowed HTTP methodsReturned in the preflight response
Access-Control-Allow-HeadersLists the allowed request headersExplicitly state custom headers such as Authorization
Access-Control-Allow-CredentialsAllows sending credentials such as cookiesWhen true, * cannot be used in Allow-Origin
Access-Control-Max-AgeNumber of seconds to cache the preflight resultIf too long, configuration changes take effect slowly

Common Misconfigurations and Their Risks

Access-Control-Allow-Origin: *

A setting that allows all origins. Appropriate for public APIs, but if set on an API that requires authentication, a malicious site can obtain a user's data. Because it cannot be combined with credentials, it does not work for APIs that use cookie-based authentication.

Unvalidated reflection of the Origin header

An implementation that returns the value of the request's Origin header directly in Allow-Origin. This effectively allows all origins, but because it can be combined with Credentials: true, it is more dangerous than *.

Allowing the null origin

Setting Access-Control-Allow-Origin: null permits requests from sandboxed iframes and local files. It is exploited in attacks where an attacker calls an API from within an iframe.

The Relationship Between CORS and CSRF

CORS and CSRF are often confused, but they protect against different things. CORS is a mechanism by which the browser controls the reading of a response; it does not block the sending of the request itself (in the case of a simple request). In other words, even if you configure CORS correctly, it may not prevent request submission via a CSRF attack. CSRF mitigation requires a separate defensive layer, such as the token method or the SameSite cookie attribute. Defense in depth combined with CSP and SSL/TLS is important.

In services that use an API key, a misconfiguration of CORS can sometimes lead to the leakage of the API key. See also Browser Extension Security, Best Practices for API Key Management, and the Startup Security Checklist.Web API security books on Amazon are recommended for learning implementation patterns.

Related Terms

Was this article helpful?

XHatena