Skip to main content
Category: Attack Techniques

Cross-Origin Resource Sharing

Also known as: CORS, CORS mechanism, cross-origin HTTP access control
Simply put

Cross-Origin Resource Sharing is a browser-enforced mechanism that controls whether scripts running on one web origin are permitted to read responses from a different origin. Browsers apply the same-origin policy by default, which restricts script access to cross-origin responses, and CORS provides a way for servers to explicitly grant or restrict that access using HTTP headers. It does not block all cross-origin requests outright, but it does govern whether the browser will expose response content to the requesting script.

Formal definition

CORS is an HTTP-header-based mechanism through which a server communicates to a browser which origins, outside the server's own origin (defined by scheme, host, and port), are permitted to have script-level access to its responses. When a browser-based script initiates a cross-origin request, the browser enforces the same-origin policy by default, restricting script access to the response unless the server includes permissive Access-Control-Allow-Origin and related headers. For requests that may have side effects (typically non-simple requests), the browser first issues a preflight OPTIONS request to determine server permissions before sending the actual request. Credential-bearing cross-origin requests require the server to respond with a specific origin value in Access-Control-Allow-Origin (wildcards are not accepted for credentialed requests) and to include Access-Control-Allow-Credentials: true; without both, the browser withholds the response from the script. CORS operates at the browser level and does not restrict server-side receipt of requests, meaning non-browser clients are unaffected by CORS headers.

Why it matters

Web applications routinely need to load resources from multiple origins, whether calling a third-party API, fetching assets from a CDN, or communicating with a separate backend service. Without a controlled mechanism for cross-origin access, browsers would leave users exposed to scripts silently reading sensitive responses from other sites using the user's credentials. CORS is the standardized mechanism that allows servers to declare which external origins may have script-level access to their responses, making legitimate cross-origin integration possible while preserving meaningful user protection.

Who it's relevant to

Web Application Developers
Developers building browser-based applications that call APIs or load resources from origins different from the application's own must understand CORS to configure requests correctly and to interpret browser-side errors. Misconfiguring CORS, such as reflecting arbitrary origins or pairing a wildcard Access-Control-Allow-Origin with Access-Control-Allow-Credentials: true (which browsers reject), can introduce security vulnerabilities or break legitimate functionality.
API and Backend Engineers
Server-side engineers are responsible for setting the Access-Control-Allow-Origin and related headers accurately. Overly permissive configurations, such as dynamically reflecting any inbound Origin header without validation, can expose authenticated endpoints to unauthorized cross-origin script access. Engineers need to understand that CORS headers control browser behavior only and do not substitute for server-side authentication and authorization controls.
Security Engineers and Penetration Testers
Security practitioners assess CORS configurations as part of web application reviews, looking for misconfigurations that permit unintended origins to read credentialed responses. Because CORS is enforced at the browser level, vulnerabilities in CORS policy affect browser-based attack scenarios specifically and must be evaluated in that context. Testing tools can identify permissive header values in responses, but confirming exploitability typically requires verifying how the server handles the Origin header dynamically.
Platform and Infrastructure Teams
Teams managing CDNs, API gateways, or reverse proxies may be responsible for injecting or overriding CORS headers at the infrastructure layer. Ensuring that infrastructure-level CORS configuration is consistent with application-level intent, and that headers are not inadvertently duplicated or contradicted, is important for both security and correct browser behavior.

Inside CORS

Same-Origin Policy (SOP)
The browser security model that restricts scripts from reading responses to cross-origin requests. It does not block all cross-origin requests outright; resources such as images and scripts embedded via HTML tags may load cross-origin, but script access to response content from XMLHttpRequest or fetch is restricted unless CORS headers permit it.
Preflight Request
An HTTP OPTIONS request automatically sent by the browser before certain cross-origin requests (those using non-simple methods or custom headers) to ask the server whether the actual request is permitted. The server must respond with appropriate CORS headers for the browser to proceed.
Access-Control-Allow-Origin
A response header that specifies which origins are permitted to read the response via script. It may contain a specific origin, or a wildcard ('*') to permit any origin, though the wildcard cannot be combined with credentialed requests.
Access-Control-Allow-Credentials
A response header that, when set to 'true' and combined with a specific (non-wildcard) origin in Access-Control-Allow-Origin, instructs the browser to expose the response to scripts when the request was sent with credentials such as cookies or HTTP authentication headers.
Access-Control-Allow-Methods
A response header returned in preflight responses that lists the HTTP methods the server permits for cross-origin requests from the specified origin.
Access-Control-Allow-Headers
A response header returned in preflight responses that lists the request headers the server permits the client to include in cross-origin requests.
Access-Control-Expose-Headers
A response header that specifies which response headers are made accessible to browser-side scripts, beyond the small set of headers exposed by default.
Simple Request
A cross-origin request that meets specific criteria (limited methods such as GET, POST, and HEAD, and a restricted set of headers) and does not trigger a preflight. The browser sends the request directly, but script access to the response is still governed by the Access-Control-Allow-Origin header.
Origin Validation
The server-side process of inspecting the request Origin header and dynamically deciding which origins to reflect in the Access-Control-Allow-Origin response header. Weak or absent validation is a common source of CORS misconfiguration vulnerabilities.

Common questions

Answers to the questions practitioners most commonly ask about CORS.

Does the browser block all cross-origin requests by default?
No. Browsers permit many cross-origin requests by default, including loading images via <img>, scripts via <script>, stylesheets, and form submissions. What the Same-Origin Policy restricts is JavaScript's ability to read the response from cross-origin requests initiated by script (such as fetch or XMLHttpRequest). CORS is the mechanism that allows servers to selectively grant script-readable access to cross-origin responses that would otherwise be restricted.
If a server responds with Access-Control-Allow-Origin: *, does the browser prevent credentials from being sent on cross-origin requests?
No. Credentials such as cookies or Authorization headers can still be sent on cross-origin requests when using a wildcard origin, provided the request itself is configured to include credentials. However, if the server responds with Access-Control-Allow-Origin: *, the browser will block the JavaScript making the request from reading the response. To allow script-readable access to credentialed cross-origin responses, the server must respond with a specific origin in Access-Control-Allow-Origin and include Access-Control-Allow-Credentials: true.
When does a cross-origin request trigger a preflight, and what does the preflight check?
A preflight is triggered when a request uses a method other than GET, HEAD, or POST, when POST is used with a content type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, or when the request includes custom headers. The browser sends an OPTIONS request to the target URL first. The server responds with CORS headers indicating which origins, methods, and headers are permitted. If the preflight succeeds, the browser proceeds with the actual request.
How should a server be configured to allow credentialed cross-origin requests from a specific frontend origin?
The server must respond with Access-Control-Allow-Origin set to the exact requesting origin (not a wildcard), and must also include Access-Control-Allow-Credentials: true. The client-side code must set credentials: 'include' in the fetch call or withCredentials: true on an XMLHttpRequest. All three conditions must be met for the browser to expose the response to the calling script.
What are the security risks of misconfiguring CORS, and which misconfiguration is most common?
The most common misconfiguration is dynamically reflecting the request's Origin header back in Access-Control-Allow-Origin without validating it against a known allowlist. This effectively grants any origin script-readable access to the response. When combined with Access-Control-Allow-Credentials: true, this can allow a malicious site to make authenticated requests to the target API and read the results on behalf of a logged-in user. Proper mitigation requires validating the incoming origin against a strict allowlist before reflecting it.
Does configuring CORS headers on a server protect the server's resources from unauthorized access?
No. CORS headers are instructions to browsers about what cross-origin script access is permitted. They are enforced by the browser, not by the server. A non-browser client such as a command-line tool or a server-side application will ignore CORS headers entirely and can read any response the server returns. CORS is not an access control mechanism and does not substitute for authentication, authorization, or other server-side controls.

Common misconceptions

Browsers block all cross-origin requests by default.
Browsers do not block all cross-origin requests. Many request types, such as loading images via <img> tags or scripts via <script> tags, are permitted cross-origin without CORS. What the Same-Origin Policy restricts is script access to the content of cross-origin responses from APIs or fetch requests. CORS selectively relaxes that restriction on response readability, not on whether requests are sent.
Using a wildcard ('*') in Access-Control-Allow-Origin prevents browsers from sending credentials on cross-origin requests.
A wildcard origin does not prevent credentials from being sent. Credentials such as cookies may still be included in cross-origin requests depending on how the request is configured. When the server responds with 'Access-Control-Allow-Origin: *', the browser will block script access to the response if the request was made with credentials, but the request itself may have already been transmitted to the server. To permit credentialed cross-origin requests with script-readable responses, the server must specify an explicit origin and set Access-Control-Allow-Credentials to 'true'.
CORS configuration on the server fully protects against cross-origin attacks such as cross-site request forgery (CSRF).
CORS governs whether browser scripts can read cross-origin responses; it does not reliably prevent state-changing requests from being delivered to the server. Simple cross-origin requests (such as form-based POST requests) may reach the server without a preflight, meaning CORS alone is not a substitute for anti-CSRF controls such as CSRF tokens or SameSite cookie attributes.

Best practices

Specify explicit, allowlisted origins in Access-Control-Allow-Origin rather than reflecting the request Origin header without validation. Validate the incoming Origin value against a known-good list before echoing it in the response.
Avoid using the wildcard ('*') for Access-Control-Allow-Origin on endpoints that handle sensitive data, authenticated sessions, or any response content that should not be universally readable by arbitrary sites.
Never combine 'Access-Control-Allow-Origin: *' with 'Access-Control-Allow-Credentials: true'. This combination is rejected by browsers and indicates a misconfiguration. Credentialed requests require an explicit, non-wildcard origin.
Restrict Access-Control-Allow-Methods and Access-Control-Allow-Headers to the minimum set required by your application. Permitting all methods or all headers unnecessarily widens the attack surface.
Do not rely on CORS as the sole control against cross-origin abuse for state-changing operations. Implement dedicated anti-CSRF controls such as synchronizer tokens or SameSite cookie attributes to protect endpoints that modify server state.
Audit CORS configuration as part of regular security assessments, specifically checking for overly permissive origin reflection patterns, subdomain wildcarding, and null origin acceptance, which are common sources of exploitable misconfiguration.