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.
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.
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.
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.
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.
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
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.
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();
} 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}) Related reading
Building a Fraud Prevention Stack
How to combine multiple detection layers into a comprehensive fraud defense.
BlogWhat Is IP Reputation and Why It Matters
One of the key signals that feeds into risk scoring and fraud prevention.
BlogWhy Static IP Blocklists Are Failing Your Business
Why binary blocking fails and risk scoring provides a smarter alternative.
GlossaryDevice Fingerprinting
How device signals complement IP intelligence for more accurate risk scoring.
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.