DEV Community

Cover image for IP Fraud Detection: VPNs, Tor, and Blacklists
APIVerve
APIVerve

Posted on • Originally published at blog.apiverve.com

IP Fraud Detection: VPNs, Tor, and Blacklists

E-commerce fraud follows a pattern. The orders look legitimate—real-seeming names, real-seeming addresses, cards that pass AVS checks. But they're placed through VPNs or Tor, using stolen credit card numbers. By the time chargebacks roll in, the goods are gone.

The thing is, these orders look suspicious if you know where to look. The IP addresses scream "I'm hiding something." VPN servers. Tor exit nodes. IPs on abuse blacklists.

The information is there. Most stores just aren't checking.

What IP Addresses Actually Tell You

Every connection to your server includes an IP address. That IP address tells you:

  1. Where they claim to be — Geographic location
  2. Whether they're hiding — VPN, proxy, or Tor usage
  3. Whether they've been bad before — Blacklist status
  4. What kind of network they're on — Residential, datacenter, mobile

None of these are definitive fraud signals on their own. But combined, they paint a picture. And certain combinations are red flags.

The Red Flags

Let me be specific about what should concern you:

Datacenter IP + No VPN signature = Bot. Real humans don't browse from AWS or Google Cloud. If you see a datacenter IP that isn't a known VPN provider, it's almost certainly automated traffic.

Tor exit node = Maximum anonymity. Tor has legitimate privacy uses, but it's also the tool of choice for people who really don't want to be identified. High-value transactions from Tor deserve scrutiny.

Blacklisted IP = Known bad actor. If an IP is on abuse blacklists, someone has already reported problems from that address. Maybe spam, maybe fraud, maybe attacks. Either way, it's a signal.

VPN + Country mismatch + High-value transaction = Suspicious. Someone claiming to be in the US, shopping with a US card, but connecting through a Netherlands VPN? Maybe they're privacy-conscious. Maybe they're not who they claim to be.

Building the Detection System

You need four data points about every IP:

async function analyzeIP(ip) {
  const apiKey = process.env.APIVERVE_KEY;

  // Fetch all signals in parallel
  const [vpn, tor, blacklist, location] = await Promise.all([
    // VPN/Proxy detection
    fetch(`https://api.apiverve.com/v1/vpndetector?ip=${ip}`, {
      headers: { 'x-api-key': apiKey }
    }).then(r => r.json()).then(r => r.data),

    // Tor exit node check
    fetch(`https://api.apiverve.com/v1/tordetect?ip=${ip}`, {
      headers: { 'x-api-key': apiKey }
    }).then(r => r.json()).then(r => r.data),

    // Blacklist check
    fetch(`https://api.apiverve.com/v1/ipblacklistlookup?ip=${ip}`, {
      headers: { 'x-api-key': apiKey }
    }).then(r => r.json()).then(r => r.data),

    // Geographic location
    fetch(`https://api.apiverve.com/v1/iplookup?ip=${ip}`, {
      headers: { 'x-api-key': apiKey }
    }).then(r => r.json()).then(r => r.data)
  ]);

  return { vpn, tor, blacklist, location };
}
Enter fullscreen mode Exit fullscreen mode

Four API calls, one Promise.all, all the data you need in ~300ms.

Scoring the Risk

Raw data isn't useful. You need a score that tells you what to do.

function calculateRiskScore(analysis, context = {}) {
  let score = 0;
  const flags = [];

  // VPN Detection
  if (analysis.vpn.is_vpn) {
    score += 25;
    flags.push('vpn_detected');
  }

  // Datacenter without VPN = likely bot
  if (analysis.vpn.is_datacenter && !analysis.vpn.is_vpn) {
    score += 45;
    flags.push('datacenter_ip_non_vpn');
  }

  // High risk assessment from VPN detector
  if (analysis.vpn.risk_level === 'High') {
    score += 20;
    flags.push('high_risk_ip');
  }

  // Tor is serious anonymization
  if (analysis.tor.isTor) {
    score += 50;
    flags.push('tor_exit_node');
  }

  // Already on blacklists
  if (analysis.blacklist.isIPBlacklisted) {
    score += 60;
    flags.push('blacklisted');
  }

  // Country mismatch (if we have claimed country)
  if (context.claimedCountry) {
    const actualCountry = analysis.location.country;
    if (actualCountry !== context.claimedCountry) {
      score += 30;
      flags.push('country_mismatch');
    }
  }

  return {
    score,
    flags,
    riskLevel: score >= 80 ? 'critical' : score >= 50 ? 'high' : score >= 25 ? 'medium' : 'low',
    recommendation: getRecommendation(score)
  };
}

function getRecommendation(score) {
  if (score >= 80) return 'block';
  if (score >= 50) return 'challenge';  // CAPTCHA, 2FA, manual review
  if (score >= 25) return 'monitor';    // Log, flag for review if issues
  return 'allow';
}
Enter fullscreen mode Exit fullscreen mode

Now you get actionable output:

{
  "score": 85,
  "flags": ["vpn_detected", "blacklisted", "country_mismatch"],
  "riskLevel": "critical",
  "recommendation": "block"
}
Enter fullscreen mode Exit fullscreen mode

Where to Check

Not every request needs full fraud analysis. Be strategic:

Always check:

  • Account registration
  • Payment/checkout
  • Password reset
  • Sensitive data access

Sometimes check:

  • Login (maybe only on failed attempts or new devices)
  • High-value actions
  • Actions that can't be undone

Don't check:

  • Static asset requests
  • Already-authenticated internal tools
  • Health check endpoints

Checking everything wastes credits and adds latency. Check the moments that matter.

Integration Example: E-Commerce Checkout

app.post('/checkout', async (req, res) => {
  const ip = req.headers['x-forwarded-for']?.split(',')[0] || req.socket.remoteAddress;
  const { billingCountry, cartTotal } = req.body;

  // Skip fraud check for tiny orders
  if (cartTotal < 50) {
    return processOrder(req, res);
  }

  const analysis = await analyzeIP(ip);
  const risk = calculateRiskScore(analysis, { claimedCountry: billingCountry });

  // Log everything for later analysis
  await logFraudCheck({
    ip,
    cartTotal,
    risk,
    analysis,
    timestamp: new Date()
  });

  if (risk.recommendation === 'block') {
    // Don't reveal why - that helps fraudsters
    return res.status(400).json({
      error: 'Unable to process order. Please contact support.'
    });
  }

  if (risk.recommendation === 'challenge') {
    // Require additional verification
    return res.json({
      requiresVerification: true,
      verificationType: cartTotal > 500 ? 'phone' : 'captcha'
    });
  }

  // Low risk - proceed
  return processOrder(req, res);
});
Enter fullscreen mode Exit fullscreen mode

Key points:

  • Skip checks for low-value orders (not worth the fraud risk)
  • Log everything (you'll want this data later)
  • Don't tell blocked users why (that's a training manual for fraudsters)
  • Scale verification to risk (high-value + suspicious = more friction)

The VPN Nuance

Here's where it gets complicated: not everyone using a VPN is a fraudster.

Legitimate VPN users:

  • Privacy-conscious individuals
  • Remote workers on corporate VPNs
  • Travelers accessing home services
  • People in countries with internet restrictions
  • Journalists, activists, at-risk individuals

VPN usage alone shouldn't block anyone. It should increase scrutiny.

The scoring system above gives VPN detection 25 points—enough to flag for monitoring, not enough to block. You need additional signals (blacklist, country mismatch, other behavioral red flags) to push into blocking territory.

Datacenter IPs without VPN signatures are different. That's someone running requests from a cloud server, not a human at a computer. That's either a bot, a scraper, or someone doing something unusual enough to spin up a server for it.

Tor Is Different

Tor is maximum-strength anonymity. The entire network is designed to make identification impossible.

There are legitimate Tor users. But the overlap between "needs absolute anonymity" and "doing something you won't like" is significant.

I'd recommend:

  • Block Tor for financial transactions
  • Require strong additional verification for account creation
  • Allow Tor for browsing/reading (why not?)
  • Let human reviewers handle edge cases

The 50-point Tor score in the system above reflects this—it's a strong signal, but not an automatic block.

Caching and Performance

IP reputation doesn't change every second. Cache results:

const cache = new Map();

async function analyzeIPCached(ip) {
  const cached = cache.get(ip);
  if (cached && Date.now() < cached.expiresAt) {
    return cached.data;
  }

  const data = await analyzeIP(ip);

  cache.set(ip, {
    data,
    expiresAt: Date.now() + (60 * 60 * 1000) // 1 hour
  });

  return data;
}
Enter fullscreen mode Exit fullscreen mode

One hour is reasonable. The same IP hitting your checkout 10 times in an hour doesn't need 10 fraud checks—one is enough.

For high-traffic sites, use Redis instead of an in-memory Map so the cache survives restarts and works across multiple servers.

What This Doesn't Catch

IP intelligence is one layer of fraud prevention. It doesn't catch:

  • Residential proxies — Fraudsters route through real home IPs
  • Mobile carriers — One IP represents thousands of users
  • Good IPs gone bad — Someone's first fraud from a clean IP
  • Sophisticated actors — State-level threats with clean infrastructure

You still need:

  • Device fingerprinting
  • Behavioral analysis
  • Payment verification
  • Manual review for edge cases

Think of IP intelligence as the first filter. It catches the lazy fraud—the people using known bad IPs, obvious VPNs, or Tor. That's a lot of fraud. But it's not all fraud.

The Numbers

What does this cost?

  • VPN detection: 1 credit
  • Tor detection: 1 credit
  • Blacklist check: 1 credit
  • IP lookup: 1 credit
  • Total: 4 credits per check

On a Starter plan ({{plan.starter.calls}} credits/month), that's thousands of fraud checks. If your checkout conversion rate is 3% and you're checking all checkouts, that supports tens of thousands of monthly visitors.

Is that worth it? Let's do different math:

  • One fraudulent order costs you the merchandise + shipping + chargeback fee (~$25) + potential account penalty
  • Average fraud case: $150-500 in losses
  • Cost of 4 credits: ~$0.01

You're paying a penny to potentially save hundreds. The ROI is obvious.


Fraud prevention isn't about catching every bad actor. It's about making fraud expensive and inconvenient enough that they go somewhere else.

IP intelligence catches the obvious stuff—the fraudsters who don't bother hiding properly, the bots pretending to be humans, the IPs with known histories. Layer it with other signals and you have a real defense.

The VPN Detector, Tor Detector, IP Blacklist Lookup, and IP Lookup APIs all work together. Same API key, same response format, four signals that tell you who you're dealing with.

Get your API key and start protecting your platform. The free tier is enough to test the entire system.


Originally published at APIVerve Blog

Top comments (0)