Last modified: 2014-11-18 18:07:25 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T21907, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 19907 - Cross-domain AJAX request support
Cross-domain AJAX request support
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
API (Other open bugs)
unspecified
All All
: Normal enhancement with 3 votes (vote)
: ---
Assigned To: Roan Kattouw
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-07-24 10:22 UTC by Tisza Gergő
Modified: 2014-11-18 18:07 UTC (History)
13 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments
Patch against r54044 (2.14 KB, patch)
2009-07-30 23:59 UTC, Alex Z.
Details

Description Tisza Gergő 2009-07-24 10:22:59 UTC
The W3C working draft on cross-origin resource sharing ( http://www.w3.org/TR/cors/ ) specifies how browsers can send AJAX requests which normally wouldn't be allowed by same-origin rules. Specifically, the repsonse of the server must contain an Access-Control-Allow-Origin header with the list of domains which are allowed to send requests. At least Firefox 3.5 and Explorer 8 already support this. Support for such a setting in the MediaWiki API could allow user scripts to perform functions that affect multiple sites (such as moving images to Commons, or combining watchlists from multiple sites), toolserver scripts to access the wikis with a sound security model (the script can instruct the browser to do stuff on a wiki without asking for passwords or session cookies), and 3rd party MediaWiki installations to have a public read/write API suitable for widgets and mashups.

The only possible security problem I can think of would be if a MediaWiki installation would allow both user scripts and page edit requests from untrusted domains. You could either disallow remote API calls to write .js pages, or leave this to be the responsibility of the one configuring the site (ie. do not enable $wgAllowUserJs / $wgUseSiteJs when API requests from untrusted domains are enabled).
Comment 1 Roan Kattouw 2009-07-25 17:49:03 UTC
Could you be more clear as to what exactly should be changed?
Comment 2 Derk-Jan Hartman 2009-07-25 19:07:04 UTC
There is some more discussion about the Access-Control-Allow-Origin header here:

https://developer.mozilla.org/En/HTTP_Access_Control
Comment 3 Alex Z. 2009-07-25 21:20:32 UTC
I imagine this would be controlled by a configuration variable, something like $wgCrossSiteAJAXdomains containing an array of domains allowed to make cross-site AJAX requests to the API by the Access-Control-Allow-Origin header. 

https://developer.mozilla.org/En/Server-Side_Access_Control gives some PHP examples of implementations.
Comment 4 Alex Z. 2009-07-30 23:59:00 UTC
Created attachment 6407 [details]
Patch against r54044

Patch to add support for Access-Control-Allow-Origin in api.php
This also uses the Access-Control-Allow-Credentials header, which I believe is required for anything that requires cookies.

I can't really test this on a localhost test wiki, so would appreciate some review.

Should we only allow this for the API, or should we do this for any entry point?

For reference: http://dev.w3.org/2006/waf/access-control/
Comment 5 Derk-Jan Hartman 2009-07-31 00:35:23 UTC
Another place where this might be useful, if not now then in future browser versions, is likely cross wikimedia project login for people with strict security settings for cookies.
Comment 6 Roan Kattouw 2009-07-31 10:19:59 UTC
(In reply to comment #4)
> Created an attachment (id=6407) [details]
> Patch against r54044
> 
> Patch to add support for Access-Control-Allow-Origin in api.php
> This also uses the Access-Control-Allow-Credentials header, which I believe is
> required for anything that requires cookies.
> 
A break; statement should be added after the second header() call in the foreach(). Other than that, this patch looks good.
Comment 7 Roan Kattouw 2009-07-31 11:07:43 UTC
"Note that in the case of credentialed requests, the Access-Control-Allow-Origin: header must not have a wildcard value of "*".   It must mention a valid origin domain."

This means that even if $wgCrossSiteAJAXdomains is set to '*', we have to output the origin domain instead of '*' in the header.
Comment 8 Alex Z. 2009-07-31 21:57:40 UTC
Done in r54127
Comment 9 Cacycle 2009-08-04 01:02:26 UTC
It would be great if the toolserver could be whitelisted on Wikipedia. I am planning a userscript/gadget that would use Diberri's Template Filler http://toolserver.org/~diberri/cgi-bin/templatefiller. Due to cross-site scripting limitations this is currently not possible.
Comment 10 Mike.lifeguard 2009-08-04 01:05:32 UTC
(In reply to comment #9)
> It would be great if the toolserver could be whitelisted on Wikipedia. I am
> planning a userscript/gadget that would use Diberri's Template Filler
> http://toolserver.org/~diberri/cgi-bin/templatefiller. Due to cross-site
> scripting limitations this is currently not possible.
> 

That should be made as a site request after this feature goes live.
Comment 11 Brett Zamir 2011-04-27 02:02:28 UTC
I understand from https://bugzilla.wikimedia.org/show_bug.cgi?id=28700#c4 that CORS, though implemented, is not configured. Can I ask what the hold-up here is? Was the code accepted simply to be available to other Mediawiki installations, or is it planned for the Wikimedia sites after some condition is met?
Comment 12 Roan Kattouw 2011-04-27 12:57:04 UTC
(In reply to comment #11)
> I understand from https://bugzilla.wikimedia.org/show_bug.cgi?id=28700#c4 that
> CORS, though implemented, is not configured. Can I ask what the hold-up here
> is? Was the code accepted simply to be available to other Mediawiki
> installations, or is it planned for the Wikimedia sites after some condition is
> met?
It was planned to be enabled at WMF, but no one ever got to it. I'll probably set it up tomorrow.
Comment 13 Brett Zamir 2011-12-20 04:30:22 UTC
Roan, is your comment 12 something you will be able to get to, or should I start a new bug for it?
Comment 14 Roan Kattouw 2011-12-20 14:40:50 UTC
(In reply to comment #13)
> Roan, is your comment 12 something you will be able to get to, or should I
> start a new bug for it?
I'm sorry for the delay, thank you for reminding me. There were serious issues with the implementation, mostly regarding caching. Those issues would have to be addressed in MediaWiki before CORS can be enabled for the API.

The root of the caching issue is comment #7: the Access-Control-Allow-Origin header we send back contains the origin domain of the foreign request, and if that header gets cached, we're screwed.

Fortunately, there's a way around this if I'm reading this correctly. For non-credentialed requests, we can send Allow-Origin: * . For credentialed requests, we have to send Allow-Origin: $ORIGIN and Allow-Credentials: true , but we can just set a no caching header for those, as credentialed requests aren't supposed to be cached anyway.

The catch here is in the definition of "credentialed request". We don't want this to mean "any request that passes a cookie" because that would be excessive; rather, we want this to mean "any request that would actually use the cookie information", i.e. requests with user-specific or privileged things. Maybe we can tie this to the cache mode?

This is interesting stuff and I have new inspiration for it now :) , so I'll poke at it today or tomorrow.
Comment 15 Tisza Gergő 2011-12-21 17:37:37 UTC
Normally, only credentialed requests pass cookies. When a client tries to send a credentialed requests, the browser will send a preflight request first (an OPTIONS request with some CORS-specific headers like Origin), and only sends the request (with cookies) if the Allow-Origin and Allow-Credentials response headers are OK. Uncredentialed requests are transmitted without cookies ( http://www.w3.org/TR/cors/#make-a-request-steps - "...and include user credentials if the credentials flag is true". Though apparently not all implementations honor this: http://stackoverflow.com/questions/6096919/android-credentials-always-sent-with-cors-requests ).
Comment 16 Krinkle 2011-12-29 11:25:26 UTC
(In reply to comment #14)
> The catch here is in the definition of "credentialed request". We don't want
> this to mean "any request that passes a cookie" because that would be
> excessive; rather, we want this to mean "any request that would actually use
> the cookie information", i.e. requests with user-specific or privileged things.

Makes sense. Although it might get a bit complicated when put into perspective of the CORS point of view.

So from the browser perspective, for requests that are NOT "credentialed" the browser will not send cookies that it has stored for that domain/path, meaning that the API will not receive them and user is treated as logged-out user.

So it looks like this looks good for us on both sides (we can't cache user-specific stuff, user-specific stuff should be in a "credentialed request", CORS specification / browsers make it impossible for non "credentialed requests" to be user specific anyway.
Comment 17 Krinkle 2011-12-29 13:09:17 UTC
by the way, before we get things mixed up:

* MediaWiki supports this already and has for over a year now. So I'm marking this bug fixed.
* Then, to have it enabled for Wikimedia sites is bug 20814
* That wasn't done yet due to cache restrictions, so the second request is to make this even better and be compatible in a special with with WMF's cache infrastructure. That feature request was logged a while ago under bug 30881.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links