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: Assessing Risk from Network Addresses
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.
IP Reputation Scoring Overview
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 Catalog
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.