2

Generally I've read the motivation for browser same-origin policies is to prevent data being obtained by an attacker because of the sending of credentials in a cross-origin request, and that if you're requesting entirely public data, the browser has no way of knowing that.

However, it does have a way of knowing whether it's sending credentials to the remote host. Why doesn't fetch, for example (see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), provide a mechanism to make a completely anonymous cross-origin request? That would prevent an attacker getting information that may be sensitive, but would allow a script to request something like a totally public RSS feed.

1

3 Answers 3

1

Why don't browsers' same-origin policies allow anonymous cross-origin requests?

They do. It is possible to send cross-origin requests using <img...> or <form ..> etc tags. One can also do this with the fetch API when setting mode to no-cors, which basically enforces the same restrictions as img or form tags regarding adding or manipulating critical headers.

Of course, one can only send the request cross-origin with no-cors but not read the response. If a cross-origin read would be allowed by default, then a script on some external site visited by a victim could fetch and then leak resources only reachable from the victims system, like resources on the internal network or resources where the access is authenticated by source IP address.

It might also be useful to look at the history of same-origin policy: in the beginning requests triggered from Javascript were restricted to same-origin. With CORS this restriction was carefully lifted in a way that nothing was possible by default which wasn't somehow possible before CORS already. This was done in order to not surprisingly add new security issues for applications which relied on the previously established behavior.

6
  • 1
    +1. Not every server that allows requests without credentials allows requests from anywhere, and protecting those servers means disallowing the attacker from reading the response (though the server still needs protection against CSRF and/or client-initiated attacks on the server such as command injection).
    – CBHacking
    May 3 at 16:02
  • I've said it elsewhere: authorizing by source IP sounds like an unbelievably dumb way of authenticating, to the point of being a security risk in itself, IMHO. Take that argument away, and I don't see why anonymous fetch requests shouldn't be allowed.
    – Jez
    May 4 at 14:07
  • 1
    @Jez: It is not unusual that some company specific information are only available from inside the company network but that they do not require any authentication since they should be open for all employees. With a user inside the company visiting some external site the external attacker owning this site might trigger a request to the internal information from the internal browser, but cannot read the response. Your proposal would allow the attacker to also read the response, i.e. exfiltrate internal information. May 4 at 14:25
  • Sounds like terrible security practice to me. It's a shame browsers have to be designed with that in mind.
    – Jez
    May 5 at 1:32
  • @Jez: You need to see the design of same origin policy in the historical context. While it might seem like a terrible idea today to treat everything in the local network as trusted, it was the common assumption 20 years ago. Changing same-origin policy to make different assumptions about how networks are protected would introduce new attack vectors. I've added some historical context to the answer, how SOP evolved. May 5 at 3:58
0

Cookies or HTTP headers in general are just one way of transmitting credentials. It's also possible that the user's IP address is used for authentication (whether that's a good idea is a different topic).

The browser cannot tell how the target application works, so it would be extremely dangerous to allow unrestricted cross-origin requests based on the assumption that all content which is accessible without cookies is automatically public.

However, the browser can ask the server which cross-origin requests should be allowed under which circumstances. This is implemented through Cross-Origin Resource Sharing. If the target application does in fact consider all resources public which are accessed without cookies or other authentication headers, it can send the appropriate CORS headers, and the browser will give JavaScript access to those resources.

6
  • Using IP address for authentication is such a stupid idea that frankly, I would dismiss that as a security risk. Or rather, I'd shift the burden of the security fix onto the server that was doing it.
    – Jez
    May 3 at 13:17
  • Within private networks, IP-based access control is probably rather common. Imagine some kind of private website which is only reachable from an internet. In your model, anybody would be able to access this site via the browser of an intranet member, because you think it's stupid to rely on the firewall and not implement application-level authentication. Besides that, handling “stupid” decisions is one of the main goals of security. It would be great if nobody ever made a mistake, but that's just not the case.
    – Ja1024
    May 3 at 13:37
  • Every intranet I've ever used required a login for any kind of sensitive information, even if it is internal. Exposing sensitive info on IP is asking for trouble.
    – Jez
    May 4 at 14:11
  • @Jez: "Every intranet I've ever used required a login for any kind of sensitive information, even if it is internal." - the behavior of browsers is not designed for your personal environment, but for a broader audience. Please don't assume that all environments work the same way as you've experienced so far. Also, "sensitive" has different meanings depending on the context. Information which might not be sensitive to share inside a company might be sensitive to share outside the company. May 4 at 14:27
  • Yeah, but the problem is that it's a trade-off. It's not "do this extra work because of security", it's "you fundamentally lose this useful functionality because of their lazy security". yeah, you can setup a proxy but that in itself is a fundamentally extra piece of work to implement and then maintain on the internet.
    – Jez
    May 5 at 1:33
0

See https://github.com/Rob--W/cors-anywhere for an interesting solution to this problem. Essentially, this is a proxy server that runs at a different domain (e.g. proxydomain.com) than the target domain (e.g. targetdomain.com) that you are trying to make the cross-origin request to.

To use this solution, client-side scripting served by origindomain.com would make a cross-origin request to the server at proxydomain.com. The server at proxydomain.com forwards the request to targetdomain.com, then the proxy will return the response from targetdomain.com, adding the CORS headers necessary to relax SOP, so that client-side scripting served by origindomain.com can access the response.

This works around the problem, allowing the anonymous cross-origin request to targetdomain.com (albeit through proxydomain.com) without opening the door to the attack that SOP aims to prevent. This is because the browser does not include credentials pertaining to targetdomain.com in the request, because the request is to proxydomain.com, not targetdomain.com. But, this is fine for anonymous requests.

1
  • Yeah, of course you can proxy. But setting up a proxy server and putting it on the public internet is a huge PITA compared to just being able to do an anonymous request from the browser.
    – Jez
    May 4 at 14:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .