/** Work out the IP address based on various globals */ function wfGetIP() { global $wgIP; # Return cached result if (!empty($wgIP)) { return $wgIP; } /* collect the originating ips */ # Client connecting to this webserver if (isset($_SERVER['REMOTE_ADDR'])) { $ipchain = array(IP::canonicalize($_SERVER['REMOTE_ADDR'])); } else { # Running on CLI? $ipchain = array('127.0.0.1'); } $ip = $ipchain[0]; # Append XFF on to $ipchain $forwardedFor = wfGetForwardedFor(); if (isset($forwardedFor)) { $xff = array_map('trim', explode(',', $forwardedFor)); $xff = array_reverse($xff); $ipchain = array_merge($ipchain, $xff); } # Step through XFF list and find the last address in the list which is a trusted server # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private) foreach ($ipchain as $i => $curIP) { $curIP = IP::canonicalize($curIP); if (wfIsTrustedProxy($curIP)) { if (isset($ipchain[$i + 1]) && IP::isPublic($ipchain[$i + 1])) { $ip = $ipchain[$i + 1]; } } else { break; } } wfDebug("IP: {$ip}\n"); $wgIP = $ip; return $ip; }
/** * Work out the IP address based on various globals * For trusted proxies, use the XFF client IP (first of the chain) * * @since 1.19 * * @throws MWException * @return string */ public function getIP() { global $wgUsePrivateIPs; # Return cached result if ($this->ip !== null) { return $this->ip; } # collect the originating ips $ip = $this->getRawIP(); # Append XFF $forwardedFor = $this->getHeader('X-Forwarded-For'); if ($forwardedFor !== false) { $ipchain = array_map('trim', explode(',', $forwardedFor)); $ipchain = array_reverse($ipchain); if ($ip) { array_unshift($ipchain, $ip); } # Step through XFF list and find the last address in the list which is a trusted server # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private) foreach ($ipchain as $i => $curIP) { $curIP = IP::canonicalize($curIP); if (wfIsTrustedProxy($curIP)) { if (isset($ipchain[$i + 1])) { if ($wgUsePrivateIPs || IP::isPublic($ipchain[$i + 1])) { $ip = $ipchain[$i + 1]; } } } else { break; } } } # Allow extensions to improve our guess wfRunHooks('GetIP', array(&$ip)); if (!$ip) { throw new MWException("Unable to determine IP"); } wfDebug("IP: {$ip}\n"); $this->ip = $ip; return $ip; }
/** * Work out the IP address based on various globals * For trusted proxies, use the XFF client IP (first of the chain) * @return string */ function wfGetIP() { global $wgUsePrivateIPs, $wgCommandLineMode; static $ip = false; # Return cached result if (!empty($ip)) { return $ip; } $ipchain = array(); /* collect the originating ips */ # Client connecting to this webserver if (isset($_SERVER['REMOTE_ADDR'])) { $ip = IP::canonicalize($_SERVER['REMOTE_ADDR']); } elseif ($wgCommandLineMode) { $ip = '127.0.0.1'; } if ($ip) { $ipchain[] = $ip; } # Append XFF on to $ipchain $forwardedFor = wfGetForwardedFor(); if (isset($forwardedFor)) { $xff = array_map('trim', explode(',', $forwardedFor)); $xff = array_reverse($xff); $ipchain = array_merge($ipchain, $xff); } # Step through XFF list and find the last address in the list which is a trusted server # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private) foreach ($ipchain as $i => $curIP) { $curIP = IP::canonicalize($curIP); if (wfIsTrustedProxy($curIP)) { if (isset($ipchain[$i + 1])) { if ($wgUsePrivateIPs || IP::isPublic($ipchain[$i + 1])) { $ip = $ipchain[$i + 1]; } } } else { break; } } # Allow extensions to improve our guess wfRunHooks('GetIP', array(&$ip)); if (!$ip) { throw new MWException("Unable to determine IP"); } wfDebug("IP: {$ip}\n"); return $ip; }
/** * Get all blocks that match any IP from an array of IP addresses * * @param Array $ipChain list of IPs (strings), usually retrieved from the * X-Forwarded-For header of the request * @param Bool $isAnon Exclude anonymous-only blocks if false * @param Bool $fromMaster Whether to query the master or slave database * @return Array of Blocks * @since 1.22 */ public static function getBlocksForIPList( array $ipChain, $isAnon, $fromMaster = false ) { if ( !count( $ipChain ) ) { return array(); } wfProfileIn( __METHOD__ ); $conds = array(); foreach ( array_unique( $ipChain ) as $ipaddr ) { # Discard invalid IP addresses. Since XFF can be spoofed and we do not # necessarily trust the header given to us, make sure that we are only # checking for blocks on well-formatted IP addresses (IPv4 and IPv6). # Do not treat private IP spaces as special as it may be desirable for wikis # to block those IP ranges in order to stop misbehaving proxies that spoof XFF. if ( !IP::isValid( $ipaddr ) ) { continue; } # Don't check trusted IPs (includes local squids which will be in every request) if ( wfIsTrustedProxy( $ipaddr ) ) { continue; } # Check both the original IP (to check against single blocks), as well as build # the clause to check for rangeblocks for the given IP. $conds['ipb_address'][] = $ipaddr; $conds[] = self::getRangeCond( IP::toHex( $ipaddr ) ); } if ( !count( $conds ) ) { wfProfileOut( __METHOD__ ); return array(); } if ( $fromMaster ) { $db = wfGetDB( DB_MASTER ); } else { $db = wfGetDB( DB_SLAVE ); } $conds = $db->makeList( $conds, LIST_OR ); if ( !$isAnon ) { $conds = array( $conds, 'ipb_anon_only' => 0 ); } $selectFields = array_merge( array( 'ipb_range_start', 'ipb_range_end' ), Block::selectFields() ); $rows = $db->select( 'ipblocks', $selectFields, $conds, __METHOD__ ); $blocks = array(); foreach ( $rows as $row ) { $block = self::newFromRow( $row ); if ( !$block->deleteIfExpired() ) { $blocks[] = $block; } } wfProfileOut( __METHOD__ ); return $blocks; }
/** * Work out the IP address based on various globals * For trusted proxies, use the XFF client IP (first of the chain) * * @since 1.19 * * @throws MWException * @return string */ public function getIP() { global $wgUsePrivateIPs; # Return cached result if ( $this->ip !== null ) { return $this->ip; } # collect the originating ips $ip = $this->getRawIP(); # Append XFF $forwardedFor = $this->getHeader( 'X-Forwarded-For' ); if ( $forwardedFor !== false ) { $ipchain = array_map( 'trim', explode( ',', $forwardedFor ) ); $ipchain = array_reverse( $ipchain ); if ( $ip ) { array_unshift( $ipchain, $ip ); } # Step through XFF list and find the last address in the list which is a # trusted server. Set $ip to the IP address given by that trusted server, # unless the address is not sensible (e.g. private). However, prefer private # IP addresses over proxy servers controlled by this site (more sensible). foreach ( $ipchain as $i => $curIP ) { $curIP = IP::sanitizeIP( IP::canonicalize( $curIP ) ); if ( wfIsTrustedProxy( $curIP ) && isset( $ipchain[$i + 1] ) ) { if ( wfIsConfiguredProxy( $curIP ) || // bug 48919; treat IP as sane IP::isPublic( $ipchain[$i + 1] ) || $wgUsePrivateIPs ) { $nextIP = IP::canonicalize( $ipchain[$i + 1] ); if ( !$nextIP && wfIsConfiguredProxy( $ip ) ) { // We have not yet made it past CDN/proxy servers of this site, // so either they are misconfigured or there is some IP spoofing. throw new MWException( "Invalid IP given in XFF '$forwardedFor'." ); } $ip = $nextIP; continue; } } break; } } # Allow extensions to improve our guess wfRunHooks( 'GetIP', array( &$ip ) ); if ( !$ip ) { throw new MWException( "Unable to determine IP." ); } wfDebug( "IP: $ip\n" ); $this->ip = $ip; return $ip; }
/** * Locates the client IP within a given XFF string * @param string $xff * @param string $address, the ip that sent this header (optional) * @return array( string, bool ) */ function efGetClientIPfromXFF($xff, $address = NULL) { if (!$xff) { return array(null, false); } // Avoid annoyingly long xff hacks $xff = trim(substr($xff, 0, 255)); $client = null; $trusted = true; // Check each IP, assuming they are separated by commas $ips = explode(',', $xff); foreach ($ips as $n => $ip) { $ip = trim($ip); // If it is a valid IP, not a hash or such if (IP::isIPAddress($ip)) { # The first IP should be the client. # Start only from the first public IP. if (is_null($client)) { if (IP::isPublic($ip)) { $client = $ip; } # Check that all servers are trusted } else { if (!wfIsTrustedProxy($ip)) { $trusted = false; break; } } } } // We still have to test if the IP that sent // this header is trusted to confirm results if ($client != $address && (!$address || !wfIsTrustedProxy($address))) { $trusted = false; } return array($client, $trusted); }
/** * Wikia: took this method from CheckUser extension * * @desc Locates the client IP within a given XFF string * @param string $xff * @return array( string, bool ) */ public static function getClientIPfromXFF($xff) { global $wgSquidServers, $wgSquidServersNoPurge; if (!$xff) { return array(null, false); } // Avoid annoyingly long xff hacks $xff = trim(substr($xff, 0, 255)); $client = null; $isSquidOnly = true; $trusted = true; // Check each IP, assuming they are separated by commas $ips = explode(',', $xff); foreach ($ips as $ip) { $ip = trim($ip); // If it is a valid IP, not a hash or such if (IP::isIPAddress($ip)) { # The first IP should be the client. # Start only from the first public IP. if (is_null($client)) { if (IP::isPublic($ip)) { $client = $ip; } } elseif (!wfIsTrustedProxy($ip)) { $isSquidOnly = false; break; } } } return array($client, $isSquidOnly); }