How sites detect proxies: three measurement layers, and which one a proxy changes
Arguments about whether a proxy “gets caught” almost always skip the layers, and so collapse into a matter of taste. A target in fact measures three independent things, and a proxy affects exactly one of them. Below is what each layer measures and how to tell whether it is even your layer. This describes the mechanism, not how to defeat it: there are no recipes here.
What a tunnel does and does not do
Start with the mechanics, because everything else follows from them. Per the HTTP specification, the CONNECT method asks a proxy to establish a tunnel and, on success, to restrict its behaviour to blind forwarding of data in both directions. Per the TLS specification, a client is required to send its ClientHello as the first TLS message. So the TLS handshake is produced by your library or browser, and a conforming proxy does not touch those bytes. SOCKS is no exception: after negotiation it too becomes a byte relay.
Hence the precise formulation worth remembering instead of the usual simplifications: through a conforming tunnel the TLS and HTTP layers keep describing your client, while the IP and TCP layers describe the proxy machine. And that split is itself an observable trait, not the absence of one.
Four cases where this does not hold
- A TLS-terminating proxy. It completes the handshake with you using a locally trusted certificate and opens its own connection outward — the target sees the proxy's handshake. This is corporate traffic inspection, and any service that asks you to install its root certificate.
- Plain unencrypted http://. There is no tunnel at all, and the proxy rebuilds the request: by specification it must replace the Host header, strip the headers listed in Connection and add Via. Field order is not significant, so it may change too. Here the target measures the proxy's HTTP stack, not yours.
- Services that forward the request instead of tunnelling: you connect to their API and they go outward on their own connection. That is not a proxy in the CONNECT sense, and the fingerprint there is theirs.
- HTTP/3. Ordinary CONNECT tunnels TCP only, so QUIC will not pass through it and the client falls back to TLS over TCP. The same client fingerprints differently with and without the proxy — not through substitution but through a change of transport.
The address layer: a database, not a measurement
A target usually learns an address's type not by itself but from a commercial database. How those databases arrive at it matters: MaxMind describes its method as analysing registration information, traffic and usage patterns — so whois is one of three inputs, not the whole answer. The fields are named literally: is_hosting_provider, is_public_proxy, is_residential_proxy, is_tor_exit_node. In the web service they have moved into an anonymizer object and remain in traits only as deprecated.
Separately there is a user_type field with a documented enum of fifteen values, and it contains hosting and residential — while a datacenter value does not exist at all. IP2Location gives the same role to usage_type, where a data centre is the code DCH, a fixed-line provider is ISP and mobile is MOB; the field ships in databases DB23–DB26 and in the proxy-detection line PX6–PX11.
The TLS layer: why JA3 gave way to JA4
JA3 built a fingerprint from ClientHello fields in the order they arrived. From Chrome 110, which reached stable in early February 2023, the browser permutes extension order by default — per handshake rather than per session, and only extension order: cipher suites and curves stay put. That was enough for JA3 to stop being a stable identifier for Chromium-family clients; it has not gone anywhere, though, and is still exposed by several large services.
JA4 sorts ciphers and extensions before hashing and ignores filler values, so permutation does not break it. A correction to the common picture: a client has not one fingerprint but a small set — session resumption changes the extension count.
The HTTP layer: order, not content
In HTTP/2 the request's pseudo-header fields are sent in an order that differs between engines — and that difference is available to a target before a single byte of page content and without any JavaScript. The public format for a passive HTTP/2 fingerprint was proposed in a 2017 Akamai paper and combines SETTINGS parameters, the window increment, priorities and pseudo-header order. Part of it has aged: priorities in Chromium-based browsers moved to a different scheme.
An important caveat: all of this applies to HTTPS inside a tunnel — for unencrypted HTTP the proxy rebuilds the request, and the target has nothing of your stack left to measure.
How to tell whether it is your layer
There is one practical payoff from separating the layers, and it is a real one: it tells you whether buying addresses is worth it at all. If a refusal is bound to a network or a country, that is the address layer, and a pool works there. If it is a browser-signature or firewall-rule refusal, those are other layers, and addresses will not help however many you have. How to tell them apart from response codes is covered in the article on 403.
And what we do not promise, so there is no misunderstanding: our product operates on the address layer. Your TLS fingerprint stays yours, and the target sees a TCP handshake from the proxy machine. Claiming that hosting addresses are indistinguishable from home ones would be untrue — the databases keep them in separate fields, and that is verifiable in a single query.
The address layer is what we sell
Rotating IPv6 from 650 ₽ for 50 threads, IPv4 from 1375 ₽ for 100, static IPv4 from 300 ₽. If the address is not what you are hitting, it is fairer to say so up front: a pool will not help.
View pricingProxies for this job
Check it with our tools
Read next
- 403 through a proxy: the site refused, the proxy refused, or the address is not the problemA 403 can come from the proxy or from the target site, and they cannot always be told apart. Where to find the Cloudflare code, which codes no address change will fix, and why proxy headers are a poor test.
- How to check a proxy: a seven-step order instead of guessworkCheck in order: reachability, authentication, exit address, geo, DNS, leaks, throughput. One command per step and the exact error code you get when that particular step is what broke.
- How many threads to set in a scraper for your proxy plan: A-Parser, Key Collector, ZennoPoster, NetpeakThreads add up across every running task, proxy checkers included. Where the ceiling is set by the program, where by the licence, and where the cheapest plan is already oversized.
