Same Origin and CORS

Much of this is taken from the same origin and CORS articles at Mozilla, which provide much more information.

  1. A web page is built from many resources of different types: HTML, images, CSS, Javascript, etc. These are loaded from various locations.
  2. The base page loads these resources by URL, which means they could be anywhere.
  3. In classic web, this no big deal. But as the web is used for more things, this starts to create problems. One in particular is called a Cross-Site Request Forgery (CSRF).
    1. When a browser sends a request to server S, all the cookies that came from S go along with that request. Hence, the request carries all relevant credentials.
    2. When a user is logged in to an account, any request from the browser will be treated as authorized.
    3. Cookies are sent only back to their origin, so if Joe, while logged into site bank, visits some other site, not-bank in a different tab or window, the bank cookies are not sent to not-bank.
    4. But some Javascript on the non-bank page could build and send a request to bank. These will send the cred cookies back to bank.
    5. Bill, who either works at non-bank, or just hacked it, could then use Javascript to construct and send a request to bank that transfers $1000 from Joe to Bill.
    6. Since it's going to bank bank's cookies, which will treat the request as authorized.
  4. A classic source of CSRF is social media and comment boards.
    1. User A posts a comment, whose text will displayed to other users on the social media site.
    2. The attacker manages to embed some JavaScript which is run in the browser of User B. (Who might just be logged into bank.)
    3. The media site is responsible to filter uploads so this cannot happen, but:
      1. Some don't do a good job.
      2. Software to clean the input can have bugs.
      3. Hackers can be clever. (You'd think they'd find honest work for that brain. At least, that's what my mother would have said.)
  5. To help limit this, browsers implement a Same-Origin Policy.
    1. A page (or other resource) is limited in its access to resources from different origins.
    2. An origin is defined as the triple of protocol, port, and hostname.
      1. Obviously, different host names give different origins.
      2. Http and https access to the same host are different origins.
      3. An IP address produces a different origin than a host name that resolves to it.
      4. File urls are different origins from any network location. Depending on the browser, all origins are different from other file origins. For some reason.
      5. The path is not part of the origin.
    3. The Javascript at origin at not-bank would be forbidden to fetch a page with origin at bank.
    4. An origin is the triple of protocol, port and host. (But not path.)
    5. Not as simple as it sounds.
      1. Pages created by Javascript generally inherit the origin of the script. (That is, starting with Window.open(), not just filling in some page with an empty body.)
      2. Special URLs like about:, and file: URLs present some subtleties.
      3. Javascript can adjust its own origin by removing subdomains (so foobar.fred.com can become fred.com. (Apparently, this capability is deprecated.)
    6. A cross-origin request can be generated by HTML, CSS, or JavaScript.
      1. Cross-origin linking, including form submission is generally allowed.
      2. Embedding is allowed
        1. Img and other media
        2. Script tag with src attribute.
        3. Linking a style sheet, though the response must have a correct Content-Type header.
        4. Even iframe, which I guess is isolated so it's security is more like linking.
      3. JavaScript fetch and the older XMLHttpRequest are not embedding, and are subject to origin rules.
        That is why the page at a file URL cant make AJAX requests to a server. But it does not explain the infuriating fact that browsers provide no control to disable this restriction for testing purpose.'
      4. Full rules are complicated.
  6. Sometimes you want to allow a cross-origin transaction which the policy would forbid. Third-party services: authentication, payment, etc.
  7. Cross-Origin Resource Sharing (CORS) is an HTTP extension to control such access.
    1. The server may send a Access-Control-Allow-Origin header to permit a page to be loaded from a different origin. The value of the header can be a origin, *, or null.
      1. An origin is like https://www.this.place, which gives protocol, host and (implicitly) port.
        1. I suppose you could supply a port.
        2. You can only give one origin. If you want to allow the source of the request, you need to give its origin.
      2. The * is supposedly any origin
        1. Doesn't seem to be in practice.
        2. It is documented to exclude requests that are marked as containing credentials. Must use the specific origin.
        3. The script you are using for the calendar assignment sends Access-Control-Allow-Origin *
      3. null seems to mean “other stuff” and you're not supposed to use it.
    2. Some requests are not “simple,” and must be “pre-flighted”
      1. Browser sends an HTTP options request first, to see if the server will accept the origin of the request.
      2. Only sends the request proper if the server seems happy.
    3. Most requests are simple. You lose simplicity when you use a method other than GET, HEAD or POST, or go beyond a short list of conventional request headers.
  8. Credentialed request. Not sure all of this is right.
    1. A Credentialed request is one that contains credentials.
    2. AFAIK, in practice that just means an option is set in the fetch or XMLHttpRequest call.
    3. The brower uses strictor CORS rules: The server must respond with the Access-Control-Allow-Credentials header.
    4. Without the flag, the client won't send things that could be credentials, such as cookies, to a different origin. (Probably will exclude any cookies, whatever they hold.)