Residential Proxies: The Traffic Your VPN Detection Misses
August 26, 2026
Datacenter IP detection is a solved problem, and its usefulness has been quietly declining for years. AWS, DigitalOcean, Hetzner and the rest publish their ranges. Checking against them is cheap and accurate, and anyone running abuse at scale stopped using them a long time ago.
What arrives instead comes from a residential IP belonging to a genuine consumer broadband connection in a plausible city, with no reputation history and nothing on any blocklist. On IP reputation alone it is indistinguishable from your best customer, because it is, in a real sense, coming from somebody's house.
Where these addresses come from
Two supply models, and the second is the one worth understanding.
Some providers pay consumers directly for bandwidth. The user installs software, agrees to terms, gets a small payment, and their connection becomes an exit node.
Most of the supply comes from SDK bundling. A free VPN, a mobile game, a browser extension, or a utility app includes a library that enrols the device into a proxy network. The disclosure is somewhere in the terms of service. The user has no practical idea their connection is being resold. This is why these networks advertise tens of millions of addresses: they are counting phones and laptops belonging to people who never knowingly opted in.
For your signup form, the consequence is that the address is real, residential, and genuinely used by an ordinary person for ordinary browsing, sometimes in the same hour that somebody else is using it to create fake accounts on your service.
Why the usual check stops working
Datacenter detection asks a question with a clean answer: does this address fall inside a range allocated to a hosting provider? Ranges are published, they change slowly, and the answer is reliable.
Residential proxy detection has no equivalent question. There is no authoritative list, exit nodes rotate constantly, and the same address may be a customer today and an exit node tomorrow. Anyone selling you a definitive residential proxy flag is selling you a probability with the uncertainty rounded off.
That does not make the problem hopeless. It makes it a scoring problem rather than a lookup problem, which changes how you should build for it.
Four signals that still work
Geolocation against everything else you know. The proxy controls the IP. It does not control the browser. A connection whose IP places it in Ohio while the browser reports Europe/Kyiv and Accept-Language: ru-RU is telling you two contradictory stories, and the browser is the one the fraudster forgot to align. This is the single highest-value check available and it costs one comparison:
const ipOffsetMinutes = geo.utcOffset; // from IP geolocation
const clientOffsetMinutes = -new Date().getTimezoneOffset();
const mismatchHours = Math.abs(ipOffsetMinutes - clientOffsetMinutes) / 60;
// 3+ hours of disagreement is worth points, not a block
Be careful with the threshold. Travellers, expatriates, and anyone who keeps their laptop on a home timezone will produce small mismatches legitimately. Large mismatches are much rarer and much more interesting.
Connection profile. Residential broadband has a shape: an ASN belonging to a consumer ISP, a static-ish address, latency consistent with the claimed location. Proxy exit traffic often arrives with latency inconsistent with its geography, because the request is travelling to the exit node before it travels to you. It is a soft signal and it is real.
Reuse across unrelated accounts over time. One address serving six signups with different names in a fortnight is anomalous for a residential connection. Families share addresses, and offices behind NAT share them heavily, so the pattern needs care. But an address that keeps producing new accounts, each with a different identity and none of which ever return, is a pattern no household produces.
Pace and rhythm at signup. Form completion time, whether fields were pasted or typed, and whether the flow was traversed in an order a human would choose. A proxy hides where a request comes from. It does nothing about how the form was filled in.
Score, do not block
The reason this belongs in a score is that every signal above has a legitimate population behind it.
Corporate VPNs produce geolocation mismatches constantly. Mobile carriers using CGNAT put thousands of subscribers behind shared addresses, so reuse counts are meaningless there. Privacy-conscious users route traffic deliberately and are frequently your most technical and most valuable customers.
So the sensible policy is graded rather than binary:
$risk = $fidro->check([
'ip' => $request->ip(),
'email' => $request->input('email'),
'timezone' => $request->input('client_timezone'),
]);
match (true) {
$risk->score >= 80 => $this->block($request),
$risk->score >= 50 => $this->requireVerification($request), // step up, do not reject
default => $this->allow($request),
};
Allow, review, block. The middle path is what makes this workable, because it lets you be suspicious without being wrong in a way that costs you a customer. A step-up check, an emailed code, a card authorisation, is cheap for a genuine user and expensive for someone creating their fortieth account.
We went through how to set those cut-offs against your own conversion data in tuning fraud thresholds, and the general mechanics of the score are in what is a risk score.
What Fidro returns
The relevant fields on a check:
{
"ip": "203.0.113.42",
"risk_score": 61,
"signals": {
"datacenter": false,
"vpn": false,
"proxy_likelihood": "medium",
"asn_type": "isp",
"geo_timezone_mismatch_hours": 4,
"distinct_accounts_30d": 5
},
"recommendation": "review"
}
Note proxy_likelihood is a band rather than a boolean, and that is deliberate. A boolean here would be dishonest given what the underlying evidence supports. The VPN detection API documents the full field set, and you can try the check against your own address on the free VPN detector.
Where this ends up
Residential proxies raise the cost of abuse rather than eliminating it, and that is the correct goal. A datacenter IP is free. A residential proxy session costs the operator real money per gigabyte, which means every control that forces an attacker onto residential infrastructure has already made their economics worse.
Push further along that line and you arrive at the thing they genuinely cannot rotate cheaply, which is a payment instrument. Emails are free, devices are cheap, residential IPs cost cents, and a stolen card costs real money and burns when it is caught. Detection at signup narrows the funnel, and the card is what closes it, which is the argument we make in catching cross-account fraud with Stripe card fingerprints.
Start with the check at the front door. The docs cover the integration, and a signup-time check takes about ten minutes to wire in.