/** * Although this function actually does the filtering, as this is a singleton pattern * we only want one instance actually using it. * * @return bool false if we should stop processing */ private function filter() { $user_ip = $this->gateway_adapter->getData_Unstaged_Escaped('user_ip'); // Determine IP status before doing anything complex $wl = DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPWhitelist')); $bl = DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPBlacklist')); if ($wl) { $this->gateway_adapter->debugarray[] = "SessionVelocity: IP present in whitelist."; return true; } if ($bl) { $this->gateway_adapter->debugarray[] = "SessionVelocity: IP present in blacklist."; return false; } // Open a session if it doesn't already exist $this->gateway_adapter->session_ensure(); // Obtain some useful information $gateway = $this->gateway_adapter->getIdentifier(); $transaction = $this->gateway_adapter->getCurrentTransaction(); $cRequestTime = $_SERVER['REQUEST_TIME']; $decayRate = $this->getVar('DecayRate', $transaction); $threshold = $this->getVar('Threshold', $transaction); $multiplier = $this->getVar('Multiplier', $transaction); // Initialize the filter $sessionData = WmfFramework::getSessionValue(self::SESS_ROOT); if (!is_array($sessionData)) { $sessionData = array(); } if (!array_key_exists($gateway, $sessionData)) { $sessionData[$gateway] = array(); } if (!array_key_exists($transaction, $sessionData[$gateway])) { $sessionData[$gateway][$transaction] = array($this::SESS_SCORE => 0, $this::SESS_TIME => $cRequestTime, $this::SESS_MULTIPLIER => 1); } $lastTime = $sessionData[$gateway][$transaction][self::SESS_TIME]; $score = $sessionData[$gateway][$transaction][self::SESS_SCORE]; $lastMultiplier = $sessionData[$gateway][$transaction][self::SESS_MULTIPLIER]; // Update the filter if it's stale if ($cRequestTime != $lastTime) { $score = max(0, $score - ($cRequestTime - $lastTime) * $decayRate); $score += $this->getVar('HitScore', $transaction) * $lastMultiplier; $sessionData[$gateway][$transaction][$this::SESS_SCORE] = $score; $sessionData[$gateway][$transaction][$this::SESS_TIME] = $cRequestTime; $sessionData[$gateway][$transaction][$this::SESS_MULTIPLIER] = $lastMultiplier * $multiplier; } // Store the results WmfFramework::setSessionValue(self::SESS_ROOT, $sessionData); // Analyze the filter results if ($score >= $threshold) { // Ahh!!! Failure!!! Sloooooooow doooowwwwnnnn $this->fraud_logger->alert("SessionVelocity: Rejecting request due to score of {$score}"); $this->sendAntifraudMessage('reject', $score, array('SessionVelocity' => $score)); $retval = false; } else { $retval = true; } $this->fraud_logger->debug("SessionVelocity: ({$gateway}, {$transaction}) Score: {$score}, " . "AllowAction: {$retval}, DecayRate: {$decayRate}, " . "Threshold: {$threshold}, Multiplier: {$lastMultiplier}"); return $retval; }
protected function filter() { $user_ip = $this->gateway_adapter->getData_Unstaged_Escaped('user_ip'); //first, handle the whitelist / blacklist before you do anything else. if (DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPWhitelist'))) { $this->gateway_adapter->debugarray[] = "IP present in whitelist."; $this->cfo->addRiskScore(0, 'IPWhitelist'); return true; } // TODO: this blacklist business should happen elsewhere, and on every hit. if (DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPBlacklist'))) { $this->gateway_adapter->debugarray[] = "IP present in blacklist."; $this->cfo->addRiskScore($this->gateway_adapter->getGlobal('IPVelocityFailScore'), 'IPBlacklist'); return true; } //if the user ip was in neither list, check the velocity. if ($this->connectToMemcache()) { $stored = $this->getMemcachedValue(); if (!$stored) { //we don't have anything in memcache for this dude yet. $this->gateway_adapter->debugarray[] = "Found no memcached data for {$user_ip}"; $this->cfo->addRiskScore(0, 'IPVelocityFilter'); //want to see the explicit zero return true; } else { $count = count($stored); $this->gateway_adapter->debugarray[] = "Found a memcached bit of data for {$user_ip}: " . print_r($stored, true); $this->gateway_logger->info("IPVelocityFilter: {$user_ip} has {$count} hits"); if ($count >= $this->gateway_adapter->getGlobal('IPVelocityThreshhold')) { $this->cfo->addRiskScore($this->gateway_adapter->getGlobal('IPVelocityFailScore'), 'IPVelocityFilter'); //cool off, sucker. Muahahaha. $this->addNowToMemcachedValue($stored, true); } else { $this->cfo->addRiskScore(0, 'IPVelocityFilter'); //want to see the explicit zero here, too. } } } //fail open, in case memcached doesn't work. return true; }