Skip to main content
Threat Detection

Risk Scoring Engine

Combine all AntiProxies databases into a single, actionable risk score. Query VPN, proxy, email, Tor, bot, and ISP data locally and compute a composite fraud score on your own infrastructure - no data ever leaves your servers.

0-100
Risk Score Range
20+
Signals Combined
<5ms
Local Scoring

How risk scoring works

The risk scoring engine is a pattern you implement in your own code, combining data from all AntiProxies databases. You control the weights, thresholds, and business logic - giving you complete flexibility without vendor lock-in.

1

Gather Signals

When a request arrives, query each AntiProxies database locally: check the IP against the VPN/proxy list, check the email against the disposable domain list, look up the IP's ASN reputation, check for Tor exit nodes, and identify datacenter traffic.

2

Assign Weights

Not all signals carry equal weight. A Tor exit node or residential proxy might add 30 points to your risk score, while a medium-abuse ISP might add 10. You define the weights based on your specific threat model.

3

Calculate Composite Score

Sum the weighted signals into a single score from 0 to 100. The score gives you a simple number to base decisions on: allow, challenge, or block. You can also add your own application-specific signals.

4

Apply Business Rules

Define thresholds that match your risk tolerance. An e-commerce site might block scores above 70 and require CAPTCHA above 40. A financial platform might have stricter thresholds. You control the logic entirely.

Example risk score breakdown

VPN Detected (NordVPN) +25
Disposable Email +30
ISP Abuse Score (45/100) +10
Not Tor, Not Datacenter +0
Total Risk Score 65/100

Recommended action: Require CAPTCHA + email verification

Available signals for risk scoring

Every AntiProxies database contributes signals you can combine into your risk score. Here are the key signals available across all databases.

Signal Weight What It Checks Source Database
VPN/Proxy Detection High Is the IP a known VPN, proxy, or anonymizer? VPN & Proxy DB
Disposable Email High Is the email domain disposable, temporary, or catch-all? Disposable Email DB
Tor Exit Node High Is the IP a known Tor exit node? Tor Nodes DB
Datacenter/Bot IP Medium Does the IP belong to a hosting provider or known bot? Bot & Datacenter DB
ISP Abuse Score Medium What is the abuse reputation of the source network? ISP Reputation DB
ISP Type Low-Medium Is the traffic from a residential, mobile, or hosting network? ISP Reputation DB
Residential Proxy High Is the IP part of a residential proxy network? VPN & Proxy DB
IP Risk Level Variable What is the individual risk level assigned to this IP? VPN & Proxy DB

Use cases for risk scoring

A composite risk score simplifies your decision-making. Instead of writing complex conditional logic for every signal, use a single number to drive your security policies.

Registration Fraud Prevention

Score every new signup by combining IP intelligence, email validation, and network reputation. High-risk registrations get blocked or sent through additional verification.

Payment Risk Assessment

Add risk scores to your checkout flow. Combine AntiProxies signals with your payment processor's fraud tools for layered protection against chargebacks and stolen cards.

Adaptive Authentication

Trigger step-up authentication based on risk score. Low-risk users get a smooth experience, while suspicious logins are challenged with CAPTCHA, 2FA, or manual review.

Content Moderation Prioritization

Use risk scores to prioritize moderation queues. Content from high-risk users gets reviewed first, helping your trust and safety team focus on the most likely abusers.

Promotional Offer Gating

Protect promotions, free trials, and referral programs. Only allow low-risk users to access valuable offers while flagging suspicious participants for review.

Compliance & Audit Trail

Log risk scores for every interaction to create an audit trail. Demonstrate to regulators and auditors that you have systematic risk assessment procedures in place.

Build your own risk scoring engine

Combine all AntiProxies databases into a single risk scoring function. All lookups are local - no network calls, no latency, no data shared externally.

PHP - Complete Risk Scoring Implementation
 25,  // Known VPN provider
        'proxy'            => 20,  // HTTP/SOCKS proxy
        'residential_proxy'=> 35,  // Residential proxy (high fraud risk)
        'tor_exit'         => 30,  // Tor exit node
        'datacenter'       => 15,  // Datacenter/hosting IP
        'disposable_email' => 30,  // Disposable email domain
        'high_abuse_isp'   => 15,  // ISP abuse score > 70
        'medium_abuse_isp' => 5,   // ISP abuse score 40-70
        'hosting_isp'      => 10,  // Traffic from hosting provider
    ];

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }

    public function score(string $ip, ?string $email = null): array {
        $score = 0;
        $signals = [];

        // 1. VPN/Proxy check
        $vpn = $this->checkVpn($ip);
        if ($vpn) {
            $key = $vpn['type'] ?? 'vpn';
            $points = self::WEIGHTS[$key] ?? self::WEIGHTS['vpn'];
            $score += $points;
            $signals[] = ['signal' => "VPN/Proxy ({$vpn['provider']})", 'points' => $points];
        }

        // 2. Tor exit node check
        $tor = $this->checkTor($ip);
        if ($tor) {
            $score += self::WEIGHTS['tor_exit'];
            $signals[] = ['signal' => 'Tor exit node', 'points' => self::WEIGHTS['tor_exit']];
        }

        // 3. Datacenter/bot check
        $bot = $this->checkBot($ip);
        if ($bot && !$bot['is_good_bot']) {
            $score += self::WEIGHTS['datacenter'];
            $signals[] = ['signal' => "Datacenter ({$bot['provider']})", 'points' => self::WEIGHTS['datacenter']];
        }

        // 4. ISP reputation
        $isp = $this->getIspReputation($ip);
        if ($isp) {
            if ($isp['abuse_score'] > 70) {
                $score += self::WEIGHTS['high_abuse_isp'];
                $signals[] = ['signal' => 'High-abuse ISP', 'points' => self::WEIGHTS['high_abuse_isp']];
            } elseif ($isp['abuse_score'] > 40) {
                $score += self::WEIGHTS['medium_abuse_isp'];
                $signals[] = ['signal' => 'Medium-abuse ISP', 'points' => self::WEIGHTS['medium_abuse_isp']];
            }
            if ($isp['is_hosting']) {
                $score += self::WEIGHTS['hosting_isp'];
                $signals[] = ['signal' => 'Hosting provider', 'points' => self::WEIGHTS['hosting_isp']];
            }
        }

        // 5. Disposable email check
        if ($email) {
            $disposable = $this->checkDisposableEmail($email);
            if ($disposable) {
                $score += self::WEIGHTS['disposable_email'];
                $signals[] = ['signal' => 'Disposable email', 'points' => self::WEIGHTS['disposable_email']];
            }
        }

        // Cap at 100
        $score = min($score, 100);

        return [
            'score'   => $score,
            'level'   => $this->riskLevel($score),
            'signals' => $signals,
            'action'  => $this->recommendedAction($score),
        ];
    }

    private function riskLevel(int $score): string {
        if ($score >= 70) return 'critical';
        if ($score >= 40) return 'high';
        if ($score >= 20) return 'medium';
        return 'low';
    }

    private function recommendedAction(int $score): string {
        if ($score >= 70) return 'block';
        if ($score >= 40) return 'challenge';  // CAPTCHA, 2FA, etc.
        if ($score >= 20) return 'monitor';
        return 'allow';
    }

    // ... checkVpn(), checkTor(), checkBot(), getIspReputation(),
    //     checkDisposableEmail() methods query local database tables
}

// Usage
$scorer = new RiskScorer($pdo);
$result = $scorer->score($_SERVER['REMOTE_ADDR'], $_POST['email'] ?? null);

// $result = [
//   'score'   => 65,
//   'level'   => 'high',
//   'signals' => [['signal' => 'VPN/Proxy (NordVPN)', 'points' => 25], ...],
//   'action'  => 'challenge'
// ]

if ($result['action'] === 'block') {
    http_response_code(403);
    exit('Access denied.');
} elseif ($result['action'] === 'challenge') {
    show_captcha();
}
Python - Risk Scoring with Detailed Breakdown
from dataclasses import dataclass, field
import sqlite3, ipaddress

@dataclass
class RiskResult:
    score: int
    level: str        # low, medium, high, critical
    action: str       # allow, monitor, challenge, block
    signals: list = field(default_factory=list)

class RiskScorer:
    """Combine all AntiProxies databases into a single risk score."""

    WEIGHTS = {
        "vpn": 25, "proxy": 20, "residential_proxy": 35,
        "tor_exit": 30, "datacenter": 15,
        "disposable_email": 30,
        "high_abuse_isp": 15, "medium_abuse_isp": 5,
        "hosting_isp": 10,
    }

    def __init__(self, db_path: str):
        self.conn = sqlite3.connect(db_path)
        self.conn.row_factory = sqlite3.Row

    def score(self, ip: str, email: str | None = None) -> RiskResult:
        total = 0
        signals = []
        ip_int = int(ipaddress.ip_address(ip))

        # Check each database locally
        for check_fn in [
            lambda: self._check_vpn(ip_int),
            lambda: self._check_tor(ip),
            lambda: self._check_bot(ip_int),
            lambda: self._check_isp(ip_int),
            lambda: self._check_email(email) if email else None,
        ]:
            result = check_fn()
            if result:
                total += result[0]
                signals.append(result[1])

        score = min(total, 100)
        level = "critical" if score >= 70 else "high" if score >= 40 else "medium" if score >= 20 else "low"
        action = "block" if score >= 70 else "challenge" if score >= 40 else "monitor" if score >= 20 else "allow"

        return RiskResult(score=score, level=level, action=action, signals=signals)

# Usage in Flask
scorer = RiskScorer("antiproxies.db")

@app.route("/register", methods=["POST"])
def register():
    risk = scorer.score(request.remote_addr, request.form.get("email"))

    if risk.action == "block":
        return jsonify({"error": "Registration blocked."}), 403
    if risk.action == "challenge":
        if not verify_captcha(request.form.get("captcha")):
            return jsonify({"error": "Please complete the CAPTCHA."}), 400

    # Proceed with registration, log the risk score
    create_user(request.form, risk_score=risk.score)
    return jsonify({"success": True})

Want to see what's in the database?

Download once, query as many times as you need. €99/year for all 22 databases, unlimited servers, and a full year of monthly updates. No usage limits, no per-query fees, no data leaving your servers.

30-day money-back guarantee
All databases included
Monthly updates