Changeset 706 for trunk/lib


Ignore:
Timestamp:
Oct 27, 2019 12:22:59 AM (5 years ago)
Author:
anonymous
Message:

Add IPIntelligenceBadIP function. Fix PHP notice for invlid IP in canonicalIPAddr(). Use CF-Connecting-IP header in getRemoteIP().

Location:
trunk/lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/Auth_SQL.inc.php

    r692 r706  
    705705            if (mysql_affected_rows($db->getDBH()) > 0) {
    706706                // User record still exists in DB. Do this to ensure user was not delete from DB between accesses. Notice "+ 1" in SQL above to ensure record is modified.
     707                $app->logMsg(sprintf('Session authenticated for user_id %s (%s).', $this->get('user_id'), $this->get('username')), LOG_DEBUG, __FILE__, __LINE__);
     708                // TODO: This auth check doesn't match parity when calling isLoggedIn($user_id) with a user_id, because the latter checks last_login_datetime in DB, and the former only checks SESSION. These two can be out-of-sync after loading DB via sdbdown.
    707709                return true;
    708710            } else {
  • trunk/lib/Utilities.inc.php

    r705 r706  
    12941294    if ($trust_all_proxies || isset($cfg['trusted_proxies']) && is_array($cfg['trusted_proxies']) && in_array($_SERVER['REMOTE_ADDR'], $cfg['trusted_proxies'], true)) {
    12951295        // Then it's probably safe to use an IP address value set in an HTTP header.
    1296         // Loop through possible IP address headers.
    1297         foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key) {
     1296        // Loop through possible IP address headers from those most likely to contain the correct value first.
     1297        // HTTP_CLIENT_IP: set by Apache Module mod_remoteip
     1298        // HTTP_REAL_IP: set by Nginx Module ngx_http_realip_module
     1299        // HTTP_CF_CONNECTING_IP: set by Cloudflare proxy
     1300        // HTTP_X_FORWARDED_FOR: defacto standard for web proxies
     1301        foreach (array('HTTP_CLIENT_IP', 'HTTP_REAL_IP', 'HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key) {
    12981302            // Loop through and if
    12991303            if (array_key_exists($key, $_SERVER)) {
     
    13021306                    $addr = preg_replace('/[^=]=/', '', $addr);
    13031307                    $addr = canonicalIPAddr(trim($addr));
    1304                     if (false !== filter_var($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
     1308                    if (false !== filter_var($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
    13051309                        return $dolookup && '' != $addr ? gethostbyaddr($addr) : $addr;
    13061310                    }
     
    13271331function canonicalIPAddr($addr)
    13281332{
     1333    if (!preg_match('/^([0-9a-f:]+|[0-9.])$/', $addr)) {
     1334        // Definitely not an IPv6 or IPv4 address.
     1335        return $addr;
     1336    }
     1337
    13291338    // Known prefix
    13301339    $v4mapped_prefix_bin = pack('H*', '00000000000000000000ffff');
     
    15271536    return $data;
    15281537}
     1538
     1539/*
     1540* Get IP address status from IP Intelligence. https://getipintel.net/free-proxy-vpn-tor-detection-api/#expected_output
     1541*
     1542* @access   public
     1543* @param    string  $ip         IP address to check.
     1544* @param    float   $threshold  Return true if the IP score is above this threshold (0-1).
     1545* @param    string  $email      Requester email address.
     1546* @return
     1547* @author   Quinn Comendant <quinn@strangecode.com>
     1548* @since    26 Oct 2019 15:39:17
     1549*/
     1550function IPIntelligenceBadIP($ip, $threshold=0.95, $email='hello@strangecode.com')
     1551{
     1552    $app =& App::getInstance();
     1553
     1554    $ch = curl_init(sprintf('http://check.getipintel.net/check.php?ip=%s&contact=%s', urlencode($ip), urlencode($email)));
     1555    curl_setopt($ch, CURLOPT_TIMEOUT, 2);
     1556    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     1557    $response = curl_exec($ch);
     1558    $errorno = curl_errno($ch);
     1559    $error = curl_error($ch);
     1560    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     1561    curl_close($ch);
     1562
     1563    if ($errorno == CURLE_OPERATION_TIMEOUTED) {
     1564        $http_code = 408;
     1565    }
     1566
     1567    switch ($http_code) {
     1568    case 200:
     1569    case 400:
     1570        // Check response value, below.
     1571        break;
     1572
     1573    case 408:
     1574        $app->logMsg(sprintf('IP Intelligence timeout', null), LOG_WARNING, __FILE__, __LINE__);
     1575        return false;
     1576    case 429:
     1577        $app->logMsg(sprintf('IP Intelligence number of allowed queries exceeded (rate limit 15 requests/minute)', null), LOG_WARNING, __FILE__, __LINE__);
     1578        return false;
     1579    default:
     1580        $app->logMsg(sprintf('IP Intelligence unexpected response (%s): %s: %s', $http_code, $error, $response), LOG_ERR, __FILE__, __LINE__);
     1581        return false;
     1582    }
     1583
     1584    switch ($response) {
     1585    case -1:
     1586        $app->logMsg('IP Intelligence: Invalid no input', LOG_WARNING, __FILE__, __LINE__);
     1587        return false;
     1588    case -2:
     1589        $app->logMsg('IP Intelligence: Invalid IP address', LOG_WARNING, __FILE__, __LINE__);
     1590        return false;
     1591    case -3:
     1592        $app->logMsg('IP Intelligence: Unroutable or private address', LOG_WARNING, __FILE__, __LINE__);
     1593        return false;
     1594    case -4:
     1595        $app->logMsg('IP Intelligence: Unable to reach database', LOG_WARNING, __FILE__, __LINE__);
     1596        return false;
     1597    case -5:
     1598        $app->logMsg('IP Intelligence: Banned: no permission or invalid email address', LOG_WARNING, __FILE__, __LINE__);
     1599        return false;
     1600    case -6:
     1601        $app->logMsg('IP Intelligence: Invalid contact information', LOG_WARNING, __FILE__, __LINE__);
     1602        return false;
     1603    default:
     1604        if (!is_numeric($response) || $response < 0 || $response >= $threshold) {
     1605            $app->logMsg(sprintf('IP Intelligence: Bad IP (%s): %s', $response, $ip), LOG_NOTICE, __FILE__, __LINE__);
     1606            return true;
     1607        }
     1608        $app->logMsg(sprintf('IP Intelligence: Good IP (%s): %s', $response, $ip), LOG_NOTICE, __FILE__, __LINE__);
     1609        return false;
     1610    }
     1611}
Note: See TracChangeset for help on using the changeset viewer.