/**
 * Checks if an IP is a trusted proxy provider.
 * Useful to tell if X-Forwarded-For data is possibly bogus.
 * Squid cache servers for the site are whitelisted.
 *
 * @param string $ip
 * @return bool
 */
function wfIsTrustedProxy($ip)
{
    $trusted = wfIsConfiguredProxy($ip);
    wfRunHooks('IsTrustedProxy', array(&$ip, &$trusted));
    return $trusted;
}
Example #2
0
	/**
	 * 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;
	}