questions about CORS

Hello! Here are some questions & answers. The goal isn't to get all the questions "right". Instead, the goal is to learn something! If you find a topic you're interested in learning more about, I'd encourage you to look it up and learn more.

can Javascript code running in a browser make any HTTP request it wants?

nope!

browsers enforce a rule called the "same-origin policy" which stops Javascript code from being able to make arbitrary HTTP requests

what's one reason JS code making a HTTP request from your browser is different from the same JS code making the exact same HTTP request from the Bad Guy's server?

two reasons:

  1. you might be on a private network (like a corporate network) that the Bad Guy doesn't have access to
  2. your browser has access to your secret cookies, and it'll include them in HTTP requests it makes by default

these are why the same-origin policy is important

is a script's "origin" the address of the page it's on (like company.com/page.html) or the address of the script (like somecdn.com/yourscript.js)?

the address of the page!

that's part of why it's so important to only include Javascript from sources you trust in your webpages.

if the JS code is on the page https://website.com/apple, is a request to https://subdomain.website.com a same-origin request?

nope!

the domain and subdomain need to be exactly the same

if the JS code is on the webpage http://website.com/apple, is a request to http://website.com/banana a same-origin request?

yes!

if the domain/subdomain, port, and protocol (http / https) are the same, it's the same origin!

does the same-origin policy block all cross-origin requests?

nope!

embedding Javascript, CSS, and images from origins is always allowed, as well as some POST requests (like form submissions).

But, for example, making an arbitrary GET request to an HTTP API isn't.

if the resource you're requesting is on the same origin, can the JS code make any request it wants?

almost, yes!

there are some forbidden headers you're never allowed to set, like Content-Length and Host. But otherwise you can send any request you want.

how do you allow a cross-origin GET request to api.yourstore.com from the origin yourstore.com?

set the Access-Control-Allow-Origin: yourstore.com header on the HTTP response!

for a basic cross-origin GET request, the browser actually will send the GET request, but it won't allow the Javascript to read the response unless the response has the right header.

It's usually better to allow a allowlist of specific origins and not *.

how do you allow a POST request of some JSON to api.yourstore.com from a different origin?

respond to the preflight OPTIONS request with the right headers!

If you're making a cross-origin POST request with some JSON, the browser won't even send the request by default. Instead, it'll send a "preflight" OPTIONS request and check the response headers.

can you get around the same-origin policy by setting a HTTP request header when you make the request?

nope!

if this were possible, it would let any attacker get around the same-origin policy just by setting a request header in their request. The server needs to be the one to allow the request.

more reading