Why do browsers have Same-Origin policies when wor

2019-02-19 06:36发布

问题:

This question is kind of a duplicate of: Why same origin policy for XMLHttpRequest

However, this answer isn't satisfactory because it doesn't address the fact that there are workarounds (as stated in the question). The answer only addresses security concerns related directly to the XMLHttpRequest but these problems are still present with JSONP (and possibly CORS, not sure). So the question still remains - Why have a strict Same Origin policy when there are workarounds like JSONP that's arguably even worse (because it's executable rather than static content)?

Here's an example: Company.com wants to make an AJAX call to some unprotected resource, like a simple public API for some data lookup. Company.com realizes that this may be insecure so they will carefully scrub the data to ensure there is no funny business. However, XMLHttpRequest does not allow this, so Company.com must use JSONP, but this would prevent the scrubbing of data and could result in an Attacker injecting arbitrary Javascript onto the page. How is this a better solution?

Another example: Company.com has a vulnerability and an attacker is able to inject Javascript onto the page which is then viewable by some user (there are a million ways this can happen; it's probably the most common website attack). With a strict Same-Origin policy, the attacker can mess with the page all day long but he can't "call home" which is an important detail because it means all your data is safe. But JSONP (and image tags) break this by allowing the attacker to scrape all your personal data from the page and send it wherever. This is still a reality even with CORS because I can tell my rogue server to allow inbound XS requests from any domain.

In other words, in what scenario does a locked-down XMLHttpRequest actually provide a greater degree of security?

回答1:

Your premise is incorrect. The Same Origin Policy says nothing about the ability of a web page to include resources on an external domain. It prevents direct access to resources via scripting that are owned by different Origins without them opting in.

Therefore CORS and JSONP are not workarounds for the Same Origin Policy. CORS enables an Origin to opt in to XHR requests with responses, and JSONP is simply a hack to allow an external reference to return dynamic data to the page.

The point here is to secure your page so that XSS is not possible in the first place. To do this the focus should be on correctly encoding text that is output to the page. This will prevent 'phoning home' as an attack will not be possible in the first place. A Content Security Policy can help neutralise any script that manages to slip through the net. A regular security vulnerability assessment on your website should pickup unencoded output - think of the CSP as filling in the gaps between when these are found and fixed, although browser support is not fully there yet - especially with Internet Explorer.

However, XMLHttpRequest does not allow this, so Company.com must use JSONP, but this would prevent the scrubbing of data and could result in an Attacker injecting arbitrary Javascript onto the page. How is this a better solution?

It is not. CORS is a better solution as the request retrieves data rather than executable code. CORS allows XMLHttpRequest to do this.

With the CORS response header Access-Control-Allow-Origin the website owner of example.com could set this to

Access-Control-Allow-Origin: https://company.com 

to allow only company.com client-side access to the data over HTTPS via a user's browser.

In this CORS scenario, example.com is trusting company.com with the data response for that particular request only. In combination with the Access-Control-Allow-Credentials header they can optionally request any authorisation cookies from the user at their browser be sent with the request, and the response to be read by JavaScript at company.com.

In a JSONP scenario, company.com would be trusting example.com with their whole Origin. This means they are trusting example.com with the whole client site security model. Example.com could do anything it wants to company.com's site. So if example.com is compromised by hackers, they could also control company.com user sessions once each user visits the page containing the <script src="https//example.com/... tag.

In other words, in what scenario does a locked-down XMLHttpRequest actually provide a greater degree of security?

Everywhere on the internet.

Say you were logged into Gmail. For argument's sake, say Gmail had an AJAX method that got your inbox contents:

https://gmail.com/services/inbox/get_conversations

Now, you are surfing the web and you land on my site, evil.com.

Evil.com contains some JavaScript to make a POST request to https://gmail.com/services/inbox/get_conversations, which will send your cookies from gmail.com back to gmail.com as you are logged in.

The service at https://gmail.com/services/inbox/get_conversations will dutifully return the contents of your inbox.

Without the Same Origin Policy locking this down, evil.com would be able to read the data in this response. i.e. any site could read your email. With the Same Origin Policy, the data is returned to the browser but no client-side script can read it apart from gmail.com (and of course any other Origins allowed by CORS). For example, in this case Google might allow the following:

Access-Control-Allow-Origin: https://google.com

Note: All of the above is made up by me as an example for illustrative purposes and in no way reflects how Google and Gmail actually do this. In principle it will be the same.