Last modified: 2014-02-06 16:47:09 UTC
I was hoping that the response from a GET request to Wikipedia's API[1] would include a CORS "Access-Control-Allow-Origin: *" header, so that it could be accessed by a client-side script running on any domain. I ended up using the JSONP response as a workaround, but this is less secure than cross-origin JSON, and shouldn't really be necessary now that browsers support CORS headers. Would it be possible to add an "Access-Control-Allow-Origin: *" header to the API's JSON responses? [1] https://en.wikipedia.org/w/api.php?action=query&list=categorymembers&cmlimit=max&cmtype=subcat&format=json&cmtitle=Category:Set_theory
Just to make sure: I guess you have seen and read https://www.mediawiki.org/wiki/Manual:CORS already?
Yes - the existing support for CORS headers requires that requests have an 'origin' parameter which matches the 'Origin' header and is one of the whitelisted MediaWiki domains.
I may be misremembering, but I believe that "Access-Control-Allow-Origin: *" would allow any random external site to fetch the CSRF tokens and such. The JSONP method explicitly disables any token fetching, and also treats the request as being from an anonymous user regardless of any login cookies. If your external site wants to interact with the API in a way JSONP doesn't allow, you should probably look into OAuth.
(In reply to comment #3) > I may be misremembering, but I believe that "Access-Control-Allow-Origin: *" > would allow any random external site to fetch the CSRF tokens and such. The > JSONP method explicitly disables any token fetching, and also treats the > request as being from an anonymous user regardless of any login cookies. > > If your external site wants to interact with the API in a way JSONP doesn't > allow, you should probably look into OAuth. Correct. CORS from untrusted domains is not secure, since that would make anti-csrf tokens useless. If you have a specific domain you want to add to the whitelist, we could discuss the merits of it individually, but * is definitely not possible.
The thing is, cross-domain XMLHttpRequests that receive "Access-Control-Allow-Origin: *" responses are not allowed[1] to contain authentication information (cookies or HTTP authentication), so they're always anonymous, so there are no anti-CSRF tokens to be stolen! If desired, it is possible to make credentials available in the request, by setting xhr.withCredentials to true in the request, setting "Access-Control-Allow-Credentials: true" in the response, and setting "Access-Control-Allow-Origin" to something other than "*" in the response. By default, though, the requests are anonymous. If xhr.withCredentials is set to true and the server returns "Access-Control-Allow-Origin: *", the browser refuses to allow the response to be read, so - as far as I can tell - there is no danger of tokens being stolen. [1] https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS#Requests_with_credentials
I've set up a demonstration which shows that cross-domain requests are forbidden from using withCredentials=true when Access-Control-Allow-Origin is set to "*". This page sets a cookie for the subdomain www.macropus.org, then uses it to fetch a token from the same subdomain, which succeeds (the cookie is sent even without withCredentials=true, as it's a request to the same subdomain): http://www.macropus.org/2014/mediawiki-cors/ This page, on a different subdomain, is able to make an unauthenticated request to the other subdomain (as the response has an "Access-Control-Allow-Origin: *" header), but is forbidden from making a request with credentials: http://git.macropus.org/mediawiki-cors-test/ The (very simple) code is here: https://github.com/hubgit/mediawiki-cors-test If there's a flaw in the security logic, it would be very useful to know about; on the other hand, I hope this will be persuasive enough to re-open this ticket. Note that for the white-listed domains, the response can still include a specific origin and so allow credentials to be sent; the "Access-Control-Allow-Origin: *" response would just be for non-whitelisted domains.
For information, on every public wikis hosted in the WMF cluster, $wgCrossSiteAJAXdomains contains the following domains: '*.wikipedia.org', '*.wikinews.org', '*.wiktionary.org', '*.wikibooks.org', '*.wikiversity.org', '*.wikisource.org', 'wikisource.org', '*.wikiquote.org', '*.wikidata.org', '*.wikivoyage.org', 'www.mediawiki.org', 'm.mediawiki.org', 'wikimediafoundation.org', 'advisory.wikimedia.org', 'auditcom.wikimedia.org', 'boardgovcom.wikimedia.org', 'board.wikimedia.org', 'chair.wikimedia.org', 'chapcom.wikimedia.org', 'collab.wikimedia.org', 'commons.wikimedia.org', 'donate.wikimedia.org', 'exec.wikimedia.org', 'grants.wikimedia.org', 'incubator.wikimedia.org', 'internal.wikimedia.org', 'login.wikimedia.org', 'meta.wikimedia.org', 'movementroles.wikimedia.org', 'office.wikimedia.org', 'otrs-wiki.wikimedia.org', 'outreach.wikimedia.org', 'quality.wikimedia.org', 'searchcom.wikimedia.org', 'spcom.wikimedia.org', 'species.wikimedia.org', 'steward.wikimedia.org', 'strategy.wikimedia.org', 'checkuser.wikimedia.org', 'internal.wikimedia.org', 'login.wikimedia.org', 'meta.wikimedia.org', 'movementroles.wikimedia.org', 'office.wikimedia.org', 'otrs-wiki.wikimedia.org', 'outreach.wikimedia.org', 'quality.wikimedia.org', 'searchcom.wikimedia.org', 'spcom.wikimedia.org', 'species.wikimedia.org', 'steward.wikimedia.org', 'strategy.wikimedia.org', 'usability.wikimedia.org', 'wikimania????.wikimedia.org', 'wikimaniateam.wikimedia.org' This allows requests from one wiki to another. This is disabled on private wikis hosted in the WMF cluster.