Support CIDR ranges in $wgSquidServersNoPurge
authorBryan Davis <bd808@wikimedia.org>
Thu, 7 Nov 2013 19:59:13 +0000 (12:59 -0700)
committerBryan Davis <bd808@wikimedia.org>
Thu, 7 Nov 2013 20:14:23 +0000 (13:14 -0700)
Use IP::isInRange() in wfIsConfiguredProxy() to allow matching against
CIDR entries in $wgSquidServersNoPurge. This will allow maintainers of
large networks to whitelist contiguous blocks of IPv4 and/or IPv6
addresses as trusted X-Forwarded-For providers.

This change also makes a small change to
WebRequestTest::testGetIpLackOfRemoteAddrThrowAnException() which was
failing under some configurations due to non-default globals
configuration.

Bug: 52829
Change-Id: I49e34bdf13e8e8c6cd169c362c283fe1034bdc6d

RELEASE-NOTES-1.23
includes/DefaultSettings.php
includes/ProxyTools.php
tests/phpunit/includes/WebRequestTest.php

index 04be2a2..7cf5c8e 100644 (file)
@@ -18,6 +18,9 @@ production.
   exception metadata to JSON and logs it to the 'exception-json' log group.
   This makes MediaWiki easier to integrate with log aggregation and analysis
   tools.
+* $wgSquidServersNoPurge now supports the use of Classless Inter-Domain
+  Routing (CIDR) notation to specify contiguous blocks of IPv4 and/or IPv6
+  addresses that should be trusted to provide X-Forwarded-For headers.
 
 === New features in 1.23 ===
 * ResourceLoader can utilize the Web Storage API to cache modules client-side.
index 92bb05e..2d1ddcb 100644 (file)
@@ -2285,7 +2285,8 @@ $wgSquidServers = array();
 
 /**
  * As above, except these servers aren't purged on page changes; use to set a
- * list of trusted proxies, etc.
+ * list of trusted proxies, etc. Supports both individual IP addresses and
+ * CIDR blocks.
  */
 $wgSquidServersNoPurge = array();
 
index bf1c405..4efd347 100644 (file)
@@ -80,7 +80,19 @@ function wfIsTrustedProxy( $ip ) {
  */
 function wfIsConfiguredProxy( $ip ) {
        global $wgSquidServers, $wgSquidServersNoPurge;
-       $trusted = in_array( $ip, $wgSquidServers ) ||
-               in_array( $ip, $wgSquidServersNoPurge );
+
+       // quick check of known proxy servers
+       $trusted = in_array( $ip, $wgSquidServers );
+
+       if ( !$trusted ) {
+               // slightly slower check to see if the ip is listed directly or in a CIDR
+               // block in $wgSquidServersNoPurge
+               foreach ( $wgSquidServersNoPurge as $block ) {
+                       if ( IP::isInRange( $ip, $block ) ) {
+                               $trusted = true;
+                               break;
+                       }
+               }
+       }
        return $trusted;
 }
index f8ed14b..06ed1fd 100644 (file)
@@ -269,6 +269,28 @@ class WebRequestTest extends MediaWikiTestCase {
                                false,
                                'With X-Forwaded-For and private IP and hook (disallowed)'
                        ),
+                       array(
+                               '12.0.0.1',
+                               array(
+                                       'REMOTE_ADDR' => 'abcd:0001:002:03:4:555:6666:7777',
+                                       'HTTP_X_FORWARDED_FOR' => '12.0.0.1, abcd:0001:002:03:4:555:6666:7777',
+                               ),
+                               array( 'ABCD:1:2:3::/64' ),
+                               array(),
+                               false,
+                               'IPv6 CIDR'
+                       ),
+                       array(
+                               '12.0.0.3',
+                               array(
+                                       'REMOTE_ADDR' => '12.0.0.1',
+                                       'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2'
+                               ),
+                               array( '12.0.0.0/24' ),
+                               array(),
+                               false,
+                               'IPv4 CIDR'
+                       ),
                );
        }
 
@@ -277,6 +299,14 @@ class WebRequestTest extends MediaWikiTestCase {
         * @covers WebRequest::getIP
         */
        public function testGetIpLackOfRemoteAddrThrowAnException() {
+               // ensure that local install state doesn't interfere with test
+               $this->setMwGlobals( array(
+                       'wgSquidServersNoPurge' => array(),
+                       'wgSquidServers' => array(),
+                       'wgUsePrivateIPs' => false,
+                       'wgHooks' => array(),
+               ) );
+
                $request = new WebRequest();
                # Next call throw an exception about lacking an IP
                $request->getIP();