1

There is something about Cross Origin Resource Sharing (CORS) that I have never truly understood, namely that with a cross-origin HTTP request, it is not the client that gets to decide which server(s) it wants to trust; instead, the server declares (in the Access-Control-Allow-Origin response header) that one or more particular clients (origins) trust it. A CORS-enabled browser will only deliver the server's response to the application if the server says that the client trusts the server. This seems like a reverse way of establishing a trust relationship between two HTTP parties.

What would make more sense to me is a mechanism similar to the following: The client declares a list of origins that it trusts; for example, via some fictional <meta allow-cross-origin="https://another-site:1234"/> element in the <head>. (Of course a browser would have to ensure that these elements are read-only and cannot be removed, modified, or augmented via scripts.)

What am I misunderstanding about CORS? Why would a client-side declaration of trusted origins not work? Why is it that the servers get to confirm which clients (origins) may trust its responses? Who is actually protected from whom by CORS? Does it protect the server, or the client?

(These are a lot of questions. I hope it's clear that I am not expecting an answer to each of these, but rather just an answer that points out my fundamental misunderstanding.)

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
  • To the downvoter, I would appreciate a hint what is wrong with my question. I am happy to edit it, explain further, or retract the question if it is truly inappropriate. – stakx - no longer contributing Aug 31 '16 at 10:07
  • 1
    The website hosting the JavaScript implicitly states that it trusts the site it is trying to retrieve the data from by requesting data from that URL in the first place. – Quentin Aug 31 '16 at 10:09
  • 1
    "the server declares (in the Access-Control-Allow-Origin response header) that one or more particular clients (origins) trust it" — No, it declares that it trusts those origins, not that they trust it. – Quentin Aug 31 '16 at 10:11
  • @Quentin: Of course. But with cross-origin requests, this implicit trust statement on the client (request) side is obviously not enough. The site from which data is requested needs to acknowledge that the client (requestor) may present its response to the running application. I don't understand why the server gets to decide that. – stakx - no longer contributing Aug 31 '16 at 10:12
  • @Quentin: "No, it declares that it trusts those origins, not that they trust it." So the essence of CORS is that the HTTP server protects its resources from foreign HTTP clients? Why then are responses still sent, even to clients whose "origin" is not listed in the Access-Control-Allow-Origin header? – stakx - no longer contributing Aug 31 '16 at 10:13
  • Because HTTP predated JavaScript, so it had to be a JavaScript mechanism to provide the protection. Then CORS came along to tell the JavaScript to selectively disable the protection when it was safe. – Quentin Aug 31 '16 at 10:14
  • @Quentin: One last feedback. You marked this question as a duplicate. Unfortunately the prior question doesn't address my misunderstanding at all. I'm sorry but I don't see how my question is a duplicate. I know what the SOP is and why cross-origin requests may not succeed without CORS set up; but I don't understand *why* CORS is the way it is. – stakx - no longer contributing Aug 31 '16 at 10:15
  • The point of same-origin policy is to prevent malicious web sites to make malicious requests on your behalf. Let's assume a web site can decide which target servers it trusts. Then the malicious web site would just add, for example, `` (or whatever you suggest) and pull all your data from Facebook as soon as you visit the malicious site. Or empty your bank account, or whatever else. – JJJ Aug 31 '16 at 10:16
  • Your original question was asking why the website initiating the request (Mallary's) couldn't give itself permission to read the data from the foreign site (Bob's). From the duplicate: *Mallary can't add this header because she has to get permission from Bob's site and it would be silly (to the point of rendering the SOP useless) for her to be able to grant herself permission.* I'm confident that the duplicate is correct. (Your subsequent comments seem to be based on a dramatically improved understanding of the situation, but they aren't the question). – Quentin Aug 31 '16 at 10:17
  • @Juhana: That is precisely why I mentioned that the browser would have to disallow manipulation of `` elements. A browser knowing about this alternative kind of CORS would block any attempts at DOM manipulation targeting this kind of `` element. – stakx - no longer contributing Aug 31 '16 at 10:18
  • @stakx — Manipulation of the meta elements is irrelevant. Mallary would just put the "Make Facebook trust my site" headers in the raw HTML sent from her server. Bob has to give the permission because Mallary is *asking for permission*. – Quentin Aug 31 '16 at 10:19
  • There is no DOM manipulation involved! The element is present in the HTML to start with. The evilhackersite.com adds that to the HTML on the server. – JJJ Aug 31 '16 at 10:20
  • @Quentin: _"Your subsequent comments seem to be based on a dramatically improved understanding of the situation."_ -- Wrong. I don't understand anything at all and feel really stupid about it, and the linked answer doesn't help me in any way. It is just restating how CORS works, but now *why* it works that way. – stakx - no longer contributing Aug 31 '16 at 10:20
  • @stakx — It does explain why it works that way. I quoted the specific bit of it which covers your question! – Quentin Aug 31 '16 at 10:21
  • I give up. I obviously didn't make it sufficiently clear what I understand already and what I don't, and the comment section is the wrong place to correct this. Sorry for the bother. I guess I'll just do some more reading and hope I'll eventually get it. – stakx - no longer contributing Aug 31 '16 at 10:23
  • @Quentin: My fundamental misunderstanding appears to be that I thought CORS was about "To which sites S1, S2, S3 may a client C send requests to?", when it's more about "Which sites M1, M2, M3 may legitimately make requests to S *on behalf of* a client of S?". Is that latter understanding roughly correct? – stakx - no longer contributing Aug 31 '16 at 11:12
  • 1
    Yes, that sounds correct. – Quentin Aug 31 '16 at 11:15
  • I do see the point others have made for XHR, but for media resources, the `crossOrigin` attribute is actually also a client-side protection (some APIs functionalities allowing the analysis of these resources won't allow to perform it on cross-origin ones ). So it actually is a two way protection. – Kaiido Sep 01 '16 at 01:36

1 Answers1

0

Client has nothing to do with it. With a CORS header you're telling the client which other servers do I trust. Those then can share your resources and client wont mind.

For example if you have two domains you tell the client so let your resources be used by your second website, you dont say i trust you as a client.

So you're protecting the server, not client. You dont want AJAX API Endpoints to be accessible by scripts hosted anywhere in the world.

A client has nothing to gain/lose from this. Its only a protection for servers because using AJAX all the URLs are clearly visible to anyone and had it been not for this protection, anybody could go ahead run their front end using your API, only servers have to lose from this so they get to decide who can use their resources.

Hanky Panky
  • 46,730
  • 8
  • 72
  • 95
  • The question is misusing the term "client" to mean "The website which hosts the page containing the JavaScript which causes the client to initiate the request" – Quentin Aug 31 '16 at 10:09
  • You are saying that CORS is actually there to protect a server asked to produce a response, not the client making the request. But this doesn't make sense to me. Why would CORS be needed at all? A HTTP server could simply look at who made the request, and then send a `2xx`/`3xx` status code or (e.g.) a `401 Unauthorized`. But with CORS, I gather that the server will produce a response anyway, but with a header that lets the client-side browser decide whether/how to process the response. Given that my understanding is correct, how does CORS add server protection over a simple `401` response? – stakx - no longer contributing Aug 31 '16 at 10:31
  • Ok so you dont think you could ever want to share your resources between 2 different domains that you own? If thats the case CORS is not for you. CORS is there to facilitate bypassing the sharing restriction when you intend to. – Hanky Panky Aug 31 '16 at 10:39
  • @HankyPanky: I must be particularly dense today, but I don't see how your last comment relates to my previous comment. If I owned & controlled two domains A and B, and A makes a request to B, then B could simply check whether the request came from A or some other domain X. If the request came in from X, then B would produce a `401 Unauthorized` response. If it came from A, it would produce a positive response. I don't see what CORS has to do with it, or why it would be needed so that my own two domains can exchange data. – stakx - no longer contributing Aug 31 '16 at 10:50
  • 1
    And by the way a web server does not know that the AJAX request was made from which site which was loaded on the clients machine at that time. – Hanky Panky Aug 31 '16 at 10:50
  • Try running a service on website A and theb request ajax access to it from site B and you ll get the answer. It isnt a direct server to server communication for them to know who to stop. The requests are coming in from a web browser on its own ip. They arent coming from website A for website B. They are coming in from John Does computer – Hanky Panky Aug 31 '16 at 10:51