Why Does Your Browser Block Cross‑Origin Requests? Understanding Same‑Origin Policy and CORS
This article explains the browser's same‑origin policy, why it exists to prevent attacks such as XSS and CSRF, how origins are defined by protocol, host and port, and how CORS, simple requests, and preflight requests enable controlled cross‑origin communication.
Introduction
In a recent front‑end interview, a high‑frequency question about POST requests led to a deep dive into same‑origin policy and cross‑origin resource sharing.
Same‑Origin Policy
The same‑origin policy (SOP) restricts how a document or script from one origin can interact with resources from another origin, protecting users from security threats such as XSS, SQL injection, OS command injection, HTTP header injection, CSRF, and others.
What Is an Origin?
An origin consists of three components: protocol (e.g., http or https), host (the domain name or IP address), and port. Two URLs are considered same‑origin only when all three match.
Examples: http://test.home.com:8080/dir/page.html – Same origin (only path differs) https://test.home.com:8080/secure.html – Different origin (protocol differs) http://test.home.com:8081/dir/etc.html – Different origin (port differs) http://online.home.com:8080/dir/other.html – Different origin (host differs)
Impact of SOP
SOP manifests in three areas:
DOM access restriction: Scripts cannot read or manipulate the DOM of pages from other origins.
Web data restriction: XMLHttpRequest or Fetch can only target resources sharing the same origin, mitigating CSRF attacks.
Network communication restriction: Browsers block cross‑origin network responses unless explicitly allowed.
CORS (Cross‑Origin Resource Sharing)
CORS provides a controlled way for browsers to relax SOP. The server includes specific HTTP headers indicating which origins are permitted. The browser first sends a preflight OPTIONS request for non‑simple requests to verify permission.
Simple Requests
A request is considered simple when it meets all of the following conditions:
Uses only the GET, HEAD, or POST method.
Contains only safe request headers such as Accept, Accept-Language, Content-Language, Last-Event-ID, and Content-Type limited to application/x-www-form-urlencoded, multipart/form-data, or text/plain.
Does not use a custom ReadableStream object.
Does not include user‑defined headers.
No event listeners are registered on XMLHttpRequestUpload.
Preflight Requests
For non‑simple requests, the browser automatically sends a preflight request containing special headers: Access-Control-Request-Method – the HTTP method to be used (e.g., POST). Access-Control-Request-Headers – a comma‑separated list of additional headers the actual request will send. Access-Control-Allow-Origin – indicates which origin may access the resource (cannot be a wildcard when credentials are included). Access-Control-Max-Age – optional cache duration for the preflight response.
If the server approves the preflight request, subsequent actual requests include an Origin header and the server responds with Access-Control-Allow-Origin.
Credentials and Wildcards
When a request includes credentials (e.g., cookies), the server must specify an explicit origin in Access-Control-Allow-Origin rather than *, otherwise the request fails. Similarly, Access-Control-Allow-Headers and Access-Control-Allow-Methods should list allowed values instead of using a wildcard to avoid security risks.
Full Request Flow
Conclusion
A preflight request is an automatic OPTIONS request sent by the browser during CORS to ensure security and let the server decide whether to allow the actual cross‑origin request.
Cross‑origin requests are blocked by default due to SOP. When a web page needs to access resources on a different origin, the browser performs a preflight request that includes headers like Origin and Access-Control-Request-Method. The server validates these headers and, if permitted, returns Access-Control-Allow-Origin and related headers, after which the browser proceeds with the actual request. This mechanism protects user data and privacy while enabling legitimate cross‑origin interactions.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
