Not really an XSS since the script include doesn't originate from the target's machines, this is a variation on CSRF known as "Javascript Hijacking" or XSSI.
The idea behind CSRF is that the attacking site (on XSS the attacking origin is the target site, in CSRF it can be anywhere) generates a API call on the target to take an action on it forging the user's credentials (because the target is using cookie authentication and the user's browser has been ordered to make the call instead of a direct target using say XHR).
XSSI is just CSRF applied to read APIs instead of action APIs. It exploits a loophole in the <script> tag allowing a js wormhole to form (APIs such as OpenSocial actually use the wormhole exploit validly).
A lot of sites out there (like the Google example, but our API makes this wrong assumption also), assume that they only need to protect against CSRF forgeries on action events and thus are vulnerable to data leak on read events as the user.
…
BTW, our (current) security policy isn't technically complete. The following exploits are currently able to be done in XSSI:
* JSONP: All JSONP can be attacked this way. Currently this is blocked due to the restriction that started this thread * Overriding Array constructor (this is the Google example below): This has been fixed in most browsers. Also, our root level JSON return is an object, not arrays. * Overriding Objects using __defineSetter__ (! see below) * Overriding Objects using UTF-7 encoding (see below)
## __defineSetter__ ##
This can be done, and most security experts icorrectly say the Array is vulnerable while the object is not: https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#Always_return_JSON_with_an_Object_on_the_outside
An example attack might look like this:
<script type="text/javascript"> Object.prototype.__defineSetter__('query', function(x) { alert(x); }); </script> <script type="text/javascript" src="http://en.wikipedia.org/w/api.php?action=query&list=watchlist&format=json"></script>
The above code run from anywhere will alert your private watchlist data (assuming you're on a browser that implements the __defineSetter__ part ECMAscript… in other words if you're in IE8 or earlier, you're safe). However, because this vulnerability/exploit is so prevalent, this was patched in many browsers. For instance, I think Firefox patched by 2009 https://bugzilla.mozilla.org/show_bug.cgi?id=470041 (the XSSI exploit dates to 2006, and became well known in 2007). However, some browsers (Opera), don't consider this a bug (it's not. The "same origin" policy is very clear on this, but this security hole became rampantly exploited by 2008) and (I think) are still are vulnerable to this attack.
## UTF-7 encoding ##
Basically you do this
<script type="text/javascript" charset="utf-7" src="http://en.wikipedia.org/w/api.php?action=query&list=watchlist&format=json&echo=UTF-7 encoded exploit"></script>
This only works if there is a parameter inside the JSON return that can be injected and returned. Since I don't think there is an API parameter we have that implements return injection (I'm not familiar with the MW API yet), I don't think this exploit can be done on our API.
If you are curious:
http://www.thespanner.co.uk/2009/11/23/bypassing-csp-for-fun-no-profit/
Net result: Our policy is a hack that protects against XSSI read exploits if your browser is less than 3 years old enough and is not Opera.
## What we should probably have done ##
A better policy is to implement a standard CSRF barrier (shared secret). State changing APIs are already protected using the edit token https://www.mediawiki.org/wiki/Manual:Edit_token (acts shared secret), but the same should be true (optionally) for all API calls, even read ones. The optional shared secret could be the session ID for all I care (remember in CSRF attacks, session token is not revealed by the attacker, but forged).
- if it is not provided, then the client is treated as an anonymous user - if it is provided but doesn't match the session then the client is treated as an anonymous user - if it is provided and matches then the client can be treated as the user
Then:
- state-changing actions should be blocked simply by the user being anonymous in the above cases - login actions should be allowed (it's irrelevant if jsonp or not since it requires the user's credentials to successfully run action=login and in our API is a two step process that blocks CSRF hard. - jsonp for state changing should be allowed (if it isn't already) since they require an edit token (shared secret) [QUESTION: is this prevented or is the API documentation in error? It should be allowed. The edittoken blocks XSSI and CSRF exploits already. "This means that things that require additional rights, such as rcprop=patrolled, won't work unless anonymous users are allowed to use them." I don't know what that means… rcprop=patrolled is a query=list operation. :-(]
Unfortunately, default anon unless secret provided for all API calls would break the bots. :-(
Take care,
terry
On May 16, 2012, at 2:28 PM, Daniel Renfro wrote:
Ah, XSS -- of course. Please excuse my temporary lapse of security-awareness. -Daniel
-----Original Message----- From: wikitech-l-bounces@lists.wikimedia.org [mailto:wikitech-l-bounces@lists.wikimedia.org] On Behalf Of Chris Steipp Sent: Wednesday, May 16, 2012 3:28 PM To: Wikimedia developers Subject: Re: [Wikitech-l] reasons for api json callback restrictions
Hi Daniel,
The restrictions prevent a class of attacks that go by the name "javascript hijacking" [1] or "xssi" [2]. This is where a malicious website (evil.com) includes the json (wrapped in the callback) from a <script src=some_url /> tag. The Javascript rules say that if evil.com included the javascript file from a script src link, then any javascript on the page (written by evil.com) has full access to the variables and javascript code on the page. So evil.com could send the tokens off to an attacker for use, or it could do a csrf attack right there from evil.com. GMail was bit by this a few years ago [3].
Hopefully that makes sense, but let me know if you want any more details!
Chris
[1] - http://en.wikipedia.org/wiki/JavaScript#Cross-site_vulnerabilities [2] - http://google-gruyere.appspot.com/part3 [3] - http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-techniques-...
On Wed, May 16, 2012 at 11:27 AM, Daniel Renfro drenfro@vistaprint.comwrote:
Can someone explain the reason for the limitations for the JSON callbacks? I'm sure there are good reasons, but they're nonobvious to me. See: < https://www.mediawiki.org/wiki/API:Data_formats#JSON_callback_restrictions >
-Daniel (User:DanielRenfro)
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l