sajad torkamani

First, what is an origin?

An origin is the combination of URL scheme, host, and port. Here are some examples of origins:

OriginSchemeHostPort
https://example.comhttpsexample.com443 (default port of https)
http://example.comhttpexample.com80 (default port of http)
http://example.com:8080httpexample.com8080

The path in the host doesn’t matter. So, the following origins would be considered the same:

  • https://example.com
  • https://example.com/foo
  • https://example.com/foo/bar

Okay, what is the same-origin policy?

The same-origin policy refers to the standardized behaviour of web browsers to prevent scripts hosted on one origin (e.g., https://foo.com) from accessing data hosted on another origin (e.g., https://bar.com).

What problem is it trying to solve?

Let’s consider what could happen if the same-origin policy wasn’t applied.

A world without the same-origin policy

  • You are logged into your bank account at https://mybank.com
  • You browse to another website: https://someforum.com.
  • Unknown to you, when you access https://someforum.com, the website initiates an Ajax request to https://mybank.com/my-account-details, reads the response and sends it to be stored on some server.
  • Your bank account details have been compromised!

Now, let’s consider how the same-origin policy mitigates this risk.

A world with the same-origin policy

  • You are logged into your bank account at https://mybank.com
  • You browse to another website: https://someforum.com.
  • Unknown to you, when you access https://someforum.com, the website initiates an Ajax request to https://mybank.com/my-account-details.
  • The browser sees that the request origin https://someforum.com is not the same as the resource origin (https://mybank.com) and that the server hasn’t made an exception for https://someforum.com via CORS so it denies the script access to the response from https://mybank.com. You get a JavaScript error like the following: Access to XMLHttpRequest at 'https://mybank.com/my-account-details' from origin 'https://some-forum.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

But can’t malicious scripts fake the Origin header?

Not from the browser. The Origin header is a forbidden header name which means it cannot be modified via JavaScript running in the browser.

But you can fake the Origin header outside the browser, with CURL for example. But in this case, the request won’t have access to the browser cookies so the scope of attacks is reduced. For example, a malicious script won’t be able to utilize cookie-based authentication.

Sources