From ce4f1221f14fa46e32baae87d23fa7b6e4cee827 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Thu, 31 Mar 2005 09:10:25 +0000 Subject: [PATCH] Adding some validation for IP determination via XFF headers, in preparation for adding ISP proxies to the trusted proxy list, which may occasionally give invalid XFF headers --- includes/ProxyTools.php | 96 +++++++++++++++++++++++++++++++++++++++++ includes/Setup.php | 27 ++---------- 2 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 includes/ProxyTools.php diff --git a/includes/ProxyTools.php b/includes/ProxyTools.php new file mode 100644 index 0000000000..d335faee93 --- /dev/null +++ b/includes/ProxyTools.php @@ -0,0 +1,96 @@ + $curIP ) { + if ( array_key_exists( $curIP, $trustedProxies ) ) { + if ( isset( $ipchain[$i + 1] ) && wfIsIPPublic( $ipchain[$i + 1] ) ) { + $ip = $ipchain[$i + 1]; + } + } else { + break; + } + } + } + + return $ip; +} + +function wfIP2Unsigned( $ip ) +{ + $n = ip2long( $ip ); + if ( $n == -1 ) { + $n = false; + } elseif ( $n < 0 ) { + $n += pow( 2, 32 ); + } + return $n; +} + +/** + * Determine if an IP address really is an IP address, and if it is public, + * i.e. not RFC 1918 or similar + */ +function wfIsIPPublic( $ip ) +{ + $n = wfIP2Unsigned( $ip ); + if ( !$n ) { + return false; + } + + static $privateRanges = false; + if ( !$privateRanges ) { + $privateRanges = array( + array( '10.0.0.0', '10.255.255.255' ), # RFC 1918 (private) + array( '172.16.0.0', '172.31.255.255' ), # " + array( '192.168.0.0', '192.168.255.255' ), # " + array( '0.0.0.0', '0.255.255.255' ), # this network + array( '127.0.0.0', '127.255.255.255' ), # loopback + ); + } + + foreach ( $privateRanges as $r ) { + $start = wfIP2Unsigned( $r[0] ); + $end = wfIP2Unsigned( $r[1] ); + if ( $n >= $start && $n <= $end ) { + return false; + } + } + return true; +} + +?> diff --git a/includes/Setup.php b/includes/Setup.php index c615667358..bfbe0c7bd3 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -16,7 +16,7 @@ if( defined( 'MEDIAWIKI' ) ) { # setting up a few globals. # -global $wgProfiling, $wgProfileSampleRate, $wgIP, $wgUseSquid, $IP; +global $wgProfiling, $wgProfileSampleRate, $wgIP, $IP; if( !isset( $wgProfiling ) ) $wgProfiling = false; @@ -41,26 +41,6 @@ if ( $wgProfiling and (0 == rand() % $wgProfileSampleRate ) ) { function wfProfileClose() {} } - - -/* collect the originating ips */ -if( $wgUseSquid && isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { - # If the web server is behind a reverse proxy, we need to find - # out where our requests are really coming from. - $hopips = array_map( 'trim', explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) ); - - $allsquids = array_merge($wgSquidServers, $wgSquidServersNoPurge); - while(in_array(trim(end($hopips)), $allsquids)){ - array_pop($hopips); - } - $wgIP = trim(end($hopips)); -} elseif( isset( $_SERVER['REMOTE_ADDR'] ) ) { - $wgIP = $_SERVER['REMOTE_ADDR']; -} else { - # Running on CLI? - $wgIP = '127.0.0.1'; -} - $fname = 'Setup.php'; wfProfileIn( $fname ); global $wgUseDynamicDates; @@ -87,8 +67,6 @@ require_once( 'WebRequest.php' ); require_once( 'LoadBalancer.php' ); require_once( 'HistoryBlob.php' ); -$wgRequest = new WebRequest(); - wfProfileOut( $fname.'-includes' ); wfProfileIn( $fname.'-misc1' ); global $wgUser, $wgLang, $wgContLang, $wgOut, $wgTitle; @@ -104,6 +82,9 @@ global $wgUseOldExistenceCheck, $wgEnablePersistentLC, $wgMasterWaitTimeout; global $wgFullyInitialised; +$wgIP = wfGetIP(); +$wgRequest = new WebRequest(); + # Useful debug output if ( $wgCommandLineMode ) { # wfDebug( '"' . implode( '" "', $argv ) . '"' ); -- 2.20.1