IP Reputation Scoring: Assessing Risk from Network Addresses

Develop comprehensive IP reputation scoring systems that assess risk levels and inform security decisions.

IP Reputation Scoring: Assessing Risk from Network Addresses
September 2, 2025
13 min read
IP Geolocation

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

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.

Tags:ip-reputationrisk-scoringsecuritythreat-intelligence