r54127 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r54126‎ | r54127 | r54128 >
Date:21:56, 31 July 2009
Author:mrzman
Status:resolved (Comments)
Tags:
Comment:
(bug 19907) Adds support for cross-domain AJAX requests to the API.
Uses the Access-Control-Allow-Origin header for browsers that support it.
<http://dev.w3.org/2006/waf/access-control/&gt;
$wgCrossSiteAJAXdomains can be set to '*' to allow requests from any domain,
an array of domains to allow, or, if $wgCrossSiteAJAXdomainsRegex is true,
an array of regexes to match against the request origin
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/api.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)

Diff [purge]

Index: trunk/phase3/api.php
@@ -69,6 +69,25 @@
7070 die(1);
7171 }
7272
 73+// Selectively allow cross-site AJAX
 74+if ( $wgCrossSiteAJAXdomains && isset($_SERVER['HTTP_ORIGIN']) ) {
 75+ if ( $wgCrossSiteAJAXdomains == '*' ) {
 76+ header( "Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}" );
 77+ header( 'Access-Control-Allow-Credentials: true' );
 78+ } elseif ( $wgCrossSiteAJAXdomainsRegex ) {
 79+ foreach ( $wgCrossSiteAJAXdomains as $regex ) {
 80+ if ( preg_match( $regex, $_SERVER['HTTP_ORIGIN'] ) ) {
 81+ header( "Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}" );
 82+ header( 'Access-Control-Allow-Credentials: true' );
 83+ break;
 84+ }
 85+ }
 86+ } elseif ( in_array( $_SERVER['HTTP_ORIGIN'], $wgCrossSiteAJAXdomains ) ) {
 87+ header( "Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}" );
 88+ header( 'Access-Control-Allow-Credentials: true' );
 89+ }
 90+}
 91+
7392 // So extensions can check whether they're running in API mode
7493 define('MW_API', true);
7594
Index: trunk/phase3/includes/DefaultSettings.php
@@ -4121,3 +4121,25 @@
41224122 * Array: Ids of namespaces to attempt match in, in desired order.
41234123 */
41244124 $wgSecondaryGoNamespaces = null;
 4125+
 4126+
 4127+/**
 4128+ * Settings for incoming cross-site AJAX requests:
 4129+ * Newer browsers support cross-site AJAX when the target resource allows requests
 4130+ * from the origin domain by the Access-Control-Allow-Origin header.
 4131+ * This is currently only used by the API (requests to api.php)
 4132+ * $wgCrossSiteAJAXdomains can be set as follows:
 4133+ *
 4134+ * - the string '*' to allow requests from any domain
 4135+ * - an array of domains to allow AJAX requests from, e.g.
 4136+ * array( 'http://en.wikipedia.org', 'http://en.wikibooks.org' );
 4137+ * - if $wgCrossSiteAJAXdomainsRegex is true, an array of regexes to be
 4138+ * matched against the request origin. Anything that matches will be allowed
 4139+ */
 4140+$wgCrossSiteAJAXdomains = array();
 4141+
 4142+/**
 4143+ * Set to true to treat $wgCrossSiteAJAXdomains as regexes instead of strings
 4144+ */
 4145+$wgCrossSiteAJAXdomainsRegex = false;
 4146+
Index: trunk/phase3/RELEASE-NOTES
@@ -76,6 +76,8 @@
7777 PHP and database version.
7878 * $wgSecondaryGoNamespaces allows an arry of namespaces to be checked when the
7979 GO button is pressed, in addition to the main namespace.
 80+* (bug 19907) $wgCrossSiteAJAXdomains and $wgCrossSiteAJAXdomainsRegex added
 81+ to control which external domains may access the API via cross-site AJAX.
8082
8183 === New features in 1.16 ===
8284
@@ -403,6 +405,9 @@
404406 * Added fields to list=search output: size, wordcount, timestamp, snippet
405407 * Where supported by backend, list=search adds a 'searchinfo' element with
406408 optional info: 'totalhits' count and 'suggestion' alternate query term
 409+* (bug 19907) $wgCrossSiteAJAXdomains added to allow specified (or all)
 410+ external domains to access api.php via AJAX, if the browser supports the
 411+ Access-Control-Allow-Origin HTTP header
407412
408413 === Languages updated in 1.16 ===
409414

Follow-up revisions

RevisionCommit summaryAuthorDate
r55400Tweak Access-Control-Allow-Origin stuff per comments on r54127....mrzman00:22, 21 August 2009

Comments

#Comment by Brion VIBBER (talk | contribs)   00:21, 20 August 2009

Hmmm... couple questions:

  • Should we be validating the http-origin header value before spitting it back to output?
  • Domains are normally case-insensitive, but this is doing case-sensitive matches
  • I think I'd rather use regexes or wildcards consistently rather than a switch that forces you to go back and change all your existing rules when you change it. (wgCrossSiteAJAXdomainsRegex)
#Comment by Mr.Z-man (talk | contribs)   00:41, 20 August 2009

With the exception of the regex part, I was going by the spec draft, which specifies a case-insensitive match.

If the value of the Origin header is not a case-sensitive match for any of the values in list of origins do not set any additional headers and terminate this set of steps.

For the majority of end users, I figured it would be simplest to just use a list of domains, I mainly added the regex option so if someone wanted to allow, say, all Wikimedia sites, they wouldn't need a list of 800 domains. Would you suggest just always using regexes, or just having 2 arrays?

What kind of validation are you thinking of?

#Comment by Brion VIBBER (talk | contribs)   20:52, 20 August 2009

Ok, case-sensitive is indeed per spec here. :) That's very weird IMO, but if that's what they say, hey that's what they specify. :)

I was thinking wildcards might be easier to work with than regexes. For instance:

$wgCrossSiteAJAXdomains = array(
  'www.mediawiki.org',
  '*.wikipedia.org',
  '*.wikimedia.org',
  '*.wiktionary.org',
 );

This wouldn't require any manual switching in of the wildcard mode; you can add a wildcard into an existing list of straight domains without having to go back and change all the other entries to a different format.

It might also be useful to allow for exceptions... either inline in the same array:

$wgCrossSiteAJAXdomains = array(
  '*.wikipedia.org',
  '*.wikimedia.org',
  '!upload.wikimedia.org',
 );

or separately:

$wgCrossSiteAJAXdomains = array(
  '*.wikipedia.org',
  '*.wikimedia.org',
  '!upload.wikimedia.org',
 );
$wgCrossSiteAJAXdomainExceptions = array(
  'upload.wikimedia.org',
 );
#Comment by Mr.Z-man (talk | contribs)   00:23, 21 August 2009

Wildcard support added in r55400

Status & tagging log