Exemplo n.º 1
0
/**
 * Checks if an IP matches a proxy we've configured.
 * @deprecated Since 1.24, use IP::isConfiguredProxy()
 *
 * @param string $ip
 * @return bool
 * @since 1.23 Supports CIDR ranges in $wgSquidServersNoPurge
 */
function wfIsConfiguredProxy($ip)
{
    wfDeprecated(__METHOD__, '1.24');
    return IP::isConfiguredProxy($ip);
}
Exemplo n.º 2
0
/**
 * Checks if an IP matches a proxy we've configured.
 * @deprecated Since 1.24, use IP::isConfiguredProxy()
 *
 * @param string $ip
 * @return bool
 * @since 1.23 Supports CIDR ranges in $wgSquidServersNoPurge
 */
function wfIsConfiguredProxy($ip)
{
    return IP::isConfiguredProxy($ip);
}
Exemplo n.º 3
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();
     if (!$ip) {
         throw new MWException('Unable to determine IP.');
     }
     # Append XFF
     $forwardedFor = $this->getHeader('X-Forwarded-For');
     if ($forwardedFor !== false) {
         $isConfigured = IP::isConfiguredProxy($ip);
         $ipchain = array_map('trim', explode(',', $forwardedFor));
         $ipchain = array_reverse($ipchain);
         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).
         # Note that some XFF values might be "unknown" with Squid/Varnish.
         foreach ($ipchain as $i => $curIP) {
             $curIP = IP::sanitizeIP(IP::canonicalize($curIP));
             if (!$curIP || !isset($ipchain[$i + 1]) || $ipchain[$i + 1] === 'unknown' || !IP::isTrustedProxy($curIP)) {
                 break;
                 // IP is not valid/trusted or does not point to anything
             }
             if (IP::isPublic($ipchain[$i + 1]) || $wgUsePrivateIPs || IP::isConfiguredProxy($curIP)) {
                 // Follow the next IP according to the proxy
                 $nextIP = IP::canonicalize($ipchain[$i + 1]);
                 if (!$nextIP && $isConfigured) {
                     // 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;
                 // keep traversing the chain
                 continue;
             }
             break;
         }
     }
     # Allow extensions to improve our guess
     Hooks::run('GetIP', array(&$ip));
     if (!$ip) {
         throw new MWException("Unable to determine IP.");
     }
     wfDebug("IP: {$ip}\n");
     $this->ip = $ip;
     return $ip;
 }
Exemplo n.º 4
0
 /**
  * Do a sanity check to make sure the session is not used from many different IP addresses
  * and store some data for later sanity checks.
  * FIXME remove this once SessionManager is considered stable
  * @private For use in Setup.php only
  * @param Session $session Defaults to the global session.
  */
 public function checkIpLimits(Session $session = null)
 {
     $session = $session ?: self::getGlobalSession();
     try {
         $ip = $session->getRequest()->getIP();
     } catch (\MWException $e) {
         return;
     }
     if ($ip === '127.0.0.1' || \IP::isConfiguredProxy($ip)) {
         return;
     }
     $now = time();
     // Record (and possibly log) that the IP is using the current session.
     // Don't touch the stored data unless we are adding a new IP or re-adding an expired one.
     // This is slightly inaccurate (when an existing IP is seen again, the expiry is not
     // extended) but that shouldn't make much difference and limits the session write frequency
     // to # of IPs / $wgSuspiciousIpExpiry.
     $data = $session->get('SessionManager-ip', array());
     if (!isset($data[$ip]) || $data[$ip] < $now) {
         $data[$ip] = time() + $this->config->get('SuspiciousIpExpiry');
         foreach ($data as $key => $expires) {
             if ($expires < $now) {
                 unset($data[$key]);
             }
         }
         $session->set('SessionManager-ip', $data);
         $logger = \MediaWiki\Logger\LoggerFactory::getInstance('session-ip');
         $logLevel = count($data) >= $this->config->get('SuspiciousIpPerSessionLimit') ? LogLevel::WARNING : (count($data) === 1 ? LogLevel::DEBUG : LogLevel::INFO);
         $logger->log($logLevel, 'Same session used from {count} IPs', array('count' => count($data), 'ips' => $data, 'session' => $session->getId(), 'user' => $session->getUser()->getName(), 'persistent' => $session->isPersistent()));
     }
     // Now do the same thing globally for the current user.
     // We are using the object cache and assume it is shared between all wikis of a farm,
     // and further assume that the same name belongs to the same user on all wikis. (It's either
     // that or a central ID lookup which would mean an extra SQL query on every request.)
     if ($session->getUser()->isLoggedIn()) {
         $userKey = 'SessionManager-ip:' . md5($session->getUser()->getName());
         $data = $this->store->get($userKey) ?: array();
         if (!isset($data[$ip]) || $data[$ip] < $now) {
             $data[$ip] = time() + $this->config->get('SuspiciousIpExpiry');
             foreach ($data as $key => $expires) {
                 if ($expires < $now) {
                     unset($data[$key]);
                 }
             }
             $this->store->set($userKey, $data, $this->config->get('SuspiciousIpExpiry'));
             $logger = \MediaWiki\Logger\LoggerFactory::getInstance('session-ip');
             $logLevel = count($data) >= $this->config->get('SuspiciousIpPerUserLimit') ? LogLevel::WARNING : (count($data) === 1 ? LogLevel::DEBUG : LogLevel::INFO);
             $logger->log($logLevel, 'Same user had sessions from {count} IPs', array('count' => count($data), 'ips' => $data, 'session' => $session->getId(), 'user' => $session->getUser()->getName(), 'persistent' => $session->isPersistent()));
         }
     }
 }