IP Reputation Scoring: Assessing Risk from Network Addresses
Develop comprehensive IP reputation scoring systems that assess risk levels and inform security decisions.
Table of Contents
Table of Contents
IP reputation scoring combines geolocation, network intelligence, and threat telemetry to assess the risk of requests. A robust system blends multiple independent signals, weights them with a transparent model, and continuously calibrates against labeled outcomes.
Overview
An IP reputation score estimates likelihood of abuse for traffic from a given address or subnet. Typical outputs:
- score: 0–100 risk (higher = riskier)
- labels: vpn, proxy, tor, datacenter, residential, bot
- confidence: 0–100 model certainty
- policy: allow, challenge, limit, block
Data Sources
Blend first- and third-party sources to reduce blind spots:
- Threat feeds: abuse databases, DDoS sources, spam/RBLs
- Network data: ASN, BGP, WHOIS, IRR, datacenter ranges
- Anonymization: VPN/proxy providers, Tor exits, relay lists
- Behavior: velocity per IP/device, endpoint diversity, session patterns
- Geo signals: country/region, time zone consistency, known hosting hubs
- Internal telemetry: failed auths, abuse reports, fraud outcomes (labels)
Signal Product
Each signal produces a normalized sub-score (0–100) and optional label:
- Blacklist presence: +40–80 risk; decays over TTL; source-weighted
- ASN type: hosting/cloud +25, residential ISP -10; mobile CGNAT +10
- Tor/VPN/Proxy: Tor +80, VPN +40–60, proxy +30–50
- Datacenter range match: +25–45; residential range: -10
- Velocity anomalies: requests/min z-score; +10–50 by deviation
- Geo inconsistency: ip-country vs user profile/device history +10–40
- Header/JA3 consistency: herd-like entropy +15–35
- Prior incidents: chargebacks/spam tied to IP/subnet +30–70 (time-decayed)
Scoring Model
Weighted sum with caps and dampening, then calibrated to risk buckets.
type SignalName =
| 'blacklist' | 'asnHosting' | 'vpn' | 'tor' | 'proxy' | 'datacenter'
| 'velocity' | 'geoMismatch' | 'headerEntropy' | 'priorIncidents'
interface SignalScore { name: SignalName; value: number; confidence: number }
function computeRiskScore(signals: SignalScore[]): { score: number; labels: string[] } {
const weights: Record<SignalName, number> = {
blacklist: 0.9,
asnHosting: 0.4,
vpn: 0.7,
tor: 1.0,
proxy: 0.6,
datacenter: 0.45,
velocity: 0.5,
geoMismatch: 0.45,
headerEntropy: 0.35,
priorIncidents: 0.8
}
let raw = 0
for (const s of signals) {
const capped = Math.min(100, Math.max(0, s.value))
raw += capped * (weights[s.name] || 0)
}
// Nonlinear dampening to avoid runaway scores from many weak signals
const normalized = Math.min(100, Math.sqrt(raw) * 10)
const labels = signals
.filter(s => ['vpn','tor','proxy','datacenter'].includes(s.name))
.map(s => s.name)
return { score: Math.round(normalized), labels }
}
Risk policy suggestions:
- 0–24 allow; 25–49 allow+observe; 50–69 challenge (captcha/OTP); 70–84 limit rate; 85–100 block
Implementation Examples
// Minimal scoring pipeline
interface ReputationInput {
ip: string
userId?: string
userCountry?: string
ipCountry?: string
asn?: number
isTor?: boolean
isVPN?: boolean
isProxy?: boolean
isDatacenter?: boolean
velocityRpm?: number
headerEntropy?: number // 0..1 (1 = very uniform)
priorIncidents?: number // count in last 90d
}
function evaluateReputation(input: ReputationInput) {
const signals: SignalScore[] = []
if (input.isTor) signals.push({ name: 'tor', value: 90, confidence: 0.9 })
if (input.isVPN) signals.push({ name: 'vpn', value: 60, confidence: 0.8 })
if (input.isProxy) signals.push({ name: 'proxy', value: 50, confidence: 0.7 })
if (input.isDatacenter) signals.push({ name: 'datacenter', value: 40, confidence: 0.7 })
if (typeof input.velocityRpm === 'number' && input.velocityRpm > 120) {
signals.push({ name: 'velocity', value: Math.min(100, (input.velocityRpm - 120) * 0.5), confidence: 0.6 })
}
if (typeof input.headerEntropy === 'number' && input.headerEntropy > 0.95) {
signals.push({ name: 'headerEntropy', value: 35, confidence: 0.6 })
}
if (typeof input.priorIncidents === 'number' && input.priorIncidents > 0) {
signals.push({ name: 'priorIncidents', value: Math.min(100, input.priorIncidents * 15), confidence: 0.7 })
}
if (input.userCountry && input.ipCountry && input.userCountry !== input.ipCountry) {
signals.push({ name: 'geoMismatch', value: 30, confidence: 0.6 })
}
const result = computeRiskScore(signals)
return {
...result,
policy: result.score >= 85 ? 'block' : result.score >= 70 ? 'limit' : result.score >= 50 ? 'challenge' : 'allow'
}
}
Calibration and Monitoring
- Calibrate thresholds on labeled outcomes (fraud chargebacks, abuse reports)
- Track precision/recall, ROC-AUC; optimize F1 or business objective
- Bucket drift detection; alert on sharp score distribution shifts
- Time-decay for stale blacklists; rolling windows for velocity
Security and Privacy
- Minimize PII; focus on network-derived signals
- Respect regional data laws; document data retention windows
- Offer challenge alternatives to blocking where possible
- Provide user appeals/override flows; audit decisions
Conclusion
Effective IP reputation scoring combines diverse signals with a calibrated model and ongoing monitoring. Start simple, measure outcomes, and iterate toward higher accuracy with minimal user friction.
Implement IP reputation scoring with our APIs: real-time signals, model hooks, and privacy-conscious defaults.