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
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.