Proxy Leak Judge
Overview
The judge shows everything a platform's servers could learn about a device that connects through a proxy, VPN or tunnel. It covers four things. Does the real IP or location leak? Is the exit IP flagged? Can a proxy be detected at all? Does the device's own setup give it away?
Running a test
In a browser
Open https://leak.realrewards.shop/?device=phone07 on the device. Tap the TEST block under the judge to start. The run takes about 15 seconds. Add &auto=1 to start it as soon as the page loads (for automation). device is just a label; use one per phone.
Nothing is stored on the server. A test session lives in memory only while it runs, and is wiped as soon as the verdict is delivered (or after 10 minutes if the run is abandoned). The server writes no logs of client IPs. Your results are kept only in your browser: the last 20 appear under Saved in this browser. Use Download JSON to keep or share one.
In the iPhone app
The Leak Probe app runs the same test through the iPhone's own app networking stack, the one native apps use, not Safari's. It adds on-device checks a website can't do. Use the app for the most accurate picture of what an app sees.
Reading results
| Status | Meaning |
|---|---|
| fail | The real IP or location leaks, the exit IP is already flagged, or the device's location contradicts its IP. |
| warn | A proxy tell: a platform could detect that a proxy or tunnel is in the path, even though nothing real leaks. |
| pass | Clean. |
| info | Context only, not scored. |
| skip | Couldn't be measured on this client, e.g. WebRTC in the app or app-only checks in a browser. |
Overall: LEAKING if any check fails, DETECTABLE if any warns, otherwise CLEAN. Score = 100 − 25 per fail − 8 per warn.
Every check
APP = native app only. Everything else runs in both the browser and the app.
Leaks: does the real identity get out?
| Check | What it measures | Bad result means |
|---|---|---|
| Exit IP consistency | Page, pings, alternate port, HTTPS and DNS-named requests all compared by source IP. | Traffic leaves from more than one IP: split routing, or the exit rotates mid-session. |
| WebRTC / UDP path | A STUN request to the judge reveals the public address UDP traffic actually leaves from. | UDP bypasses the tunnel and shows your real IP. No public address at all means UDP is blocked, which isn't a leak. |
| QUIC / HTTP/3 path | HTTP/3 requests over UDP 443, the protocol most large native apps use. | QUIC arrives from a different IP than the exit, so it bypasses the tunnel. If it stays on TCP, QUIC is blocked. |
| IPv6 leak | A request to an IPv6-only hostname. | IPv6 reaches the server from a different network than the IPv4 exit. |
| DNS leak | Unique per-test hostnames resolve through the judge's own DNS server. It records which resolver asked, and the client subnet (ECS) the resolver forwarded. | The resolver is in a different country from the exit, or ECS reveals your real network. |
| Raw UDP path APP | Raw UDP packets over IPv4 and IPv6 to an echo port. | UDP leaves from a different network than the exit. |
Network identity: what the exit IP looks like
| Check | What it measures | Bad result means |
|---|---|---|
| Exit IP type | Mobile carrier, residential or datacenter, from ip-api.com and proxycheck.io. Shows the ISP and the network owner. | A datacenter or hosting IP gets flagged on sight. A business line is a weaker tell. |
| IP reputation | Proxy, VPN and Tor lists, plus a risk score. | The exit is already listed as a proxy or VPN. |
| Proxy headers | Via, X-Forwarded-For, Forwarded and about 20 similar headers. | An HTTP proxy rewrote the request. |
| Reverse DNS | The exit IP's PTR hostname. | The name looks like hosting, static or VPN infrastructure. |
| Open ports on exit IP | A short TCP scan of the exit IP: SOCKS, Squid, OpenVPN, PPTP, RDP, SSH, ADB and others. | Proxy or remote-access services are running on the "residential" IP. |
Geography: does the device match the IP?
| Check | What it measures | Bad result means |
|---|---|---|
| Distance plausibility | Physics. Light in fibre covers about 100 km per ms of round trip, so the IP's location caps the RTT a device actually there could have. | The device is thousands of km farther away than its IP claims. No tunnel can fix this. |
| Timezone vs IP | Device timezone vs the IP's timezone. | A different UTC offset: the device is clearly configured for elsewhere. |
| Language / region | Locale region and languages vs IP country. | Region doesn't match (weak on its own). |
Proxy tells: can a proxy be detected?
| Check | What it measures | Bad result means |
|---|---|---|
| TCP/IP stack vs User-Agent | A passive fingerprint (p0f-style) of the connection's first packet (the SYN): TCP option order, window size, TTL. | The stack is Linux but the device claims iPhone, so a proxy is terminating the connection. |
| Latency triangulation | The kernel's TCP RTT to whatever terminated the connection vs the RTT the device measures itself. | A hidden hop between the device and the exit (the proxy leg). |
| MTU / MSS | The maximum segment size in the SYN. | Tunnel overhead (VPN/WireGuard) is visible. 1400–1499 is normal for mobile and PPPoE. |
| TTL / hop count | Hops from the TCP peer. | Context only. |
| VPN interface APP | utun/ipsec/ppp interfaces with a routable address, and VPN keys in the system's __SCOPED__ proxy list. These are what app SDKs read. System, ULA and Wi-Fi Calling tunnels are ignored. | A VPN app on the phone is visible to every app. |
| System proxy settings APP | HTTP/HTTPS/SOCKS/PAC proxy in the Wi-Fi settings. | Apps can read the proxy configuration. |
Device
| Check | What it measures | Bad result means |
|---|---|---|
| Clock skew | Device clock vs server clock. | The time was set manually. |
| Automation flags | navigator.webdriver (browser only). | The browser is being driven by automation. |
| Network path APP | Active interfaces (Wi-Fi/cellular), model, iOS version. | Context only. |
Fixing common results
| Result | Fix |
|---|---|
| Timezone fail | Settings → General → Date & Time: turn off Set Automatically and pick the exit's city. Keep each phone on one exit. |
| IP reputation fail | The exit itself is burned. Ask the provider for a different IP, preferably from a mobile-carrier pool. |
| Datacenter IP | Use a residential or mobile exit instead. |
| DNS leak | Make the router or VPN resolve DNS through the tunnel, not through the ISP. |
| WebRTC / UDP / QUIC leak | Enable UDP relay in the router's proxy client, or block UDP to the WAN outside the tunnel. |
| IPv6 leak | Disable IPv6 on the router's LAN, or route it through the tunnel. |
| VPN interface visible | Move the tunnel off the phone and onto the router. |
| SIM / location | Remove SIMs whose country doesn't match the exit, and turn off Location Services. These are on-device signals no network fix covers. |
What can't be faked
Three tells come from how the connection is built, not from configuration:
- TCP fingerprint. Proxies (SOCKS, HTTP and similar) open new connections from their own Linux stack. A layer-3 tunnel (WireGuard, OpenVPN tun) to an exit you control forwards the phone's own packets and passes.
- Latency triangulation. Same cause, same fix: with a layer-3 tunnel the whole path is one TCP connection.
- Distance. Physics. A device on another continent from its IP is at least 100 ms too slow for its IP's location, whatever the tunnel. Adding delay makes it worse. The only fixes are physical: put the device near its exit, or use exits near the device.
iPhone app: Leak Probe
Why use the app? The browser test shows what Safari gives away. Native apps aren't Safari. They have their own network code, and they can read things about the phone that a web page never can. A clean result in Safari doesn't mean a clean result in the apps. To find out whether an app can see your proxy, test from an app.
| Browser test | Leak Probe app | |
|---|---|---|
| Network code | Safari / WebKit | The iOS app networking stack, the one native apps use |
| UDP & QUIC | Only through WebRTC | Raw UDP over IPv4 and IPv6, native STUN and HTTP/3, the way apps send them |
| VPN on the phone | Can't see it | Sees VPN interfaces exactly as app SDKs do |
| Proxy in Wi-Fi settings | Can't see it | Reads the system proxy config |
| Safari privacy features | iCloud Private Relay, Lockdown Mode and WebRTC IP hiding can make the result look cleaner than reality | Not affected. It sees what any app sees |
| Automation | Open a URL | leakprobe://run starts a run from the Mac that drives the phone |
| Setup | None | Xcode and an Apple developer account (free works for 7 days) |
Use the browser for a quick check on any device. Use the app before trusting a phone with real accounts.
Build & install
- Unzip and open
LeakProbe.xcodeprojin Xcode 16 or later. - Target LeakProbe → Signing & Capabilities: pick your Team. Change the bundle ID if it's taken.
- Connect the iPhone with Developer Mode on, select it, and press Run (⌘R).
A free Apple ID works, but the app expires after 7 days. A paid developer account lasts a year.
From the command line:
xcodebuild -project LeakProbe.xcodeproj -scheme LeakProbe \
-destination 'generic/platform=iOS' -allowProvisioningUpdates \
DEVELOPMENT_TEAM=<TEAM_ID> build
xcrun devicectl device install app --device <DEVICE_ID> <path>/LeakProbe.app
Run remotely
The URL scheme leakprobe://run?device=phone07 starts a run. You can trigger it from the Mac that drives the phone:
xcrun devicectl device process launch --terminate-existing --device <DEVICE_ID> \
--payload-url "leakprobe://run?device=phone07" shop.realrewards.leakprobe
Privacy
Results stay on the phone. Use Share JSON to export one. The server keeps nothing.
API
POST /api/session?device=NAME → { sid, zone, v4, v6, https_origin, ... }
GET /api/ping?sid= RTT sample (TCP_INFO recorded)
GET /api/probe/{alt|v6|tls|dns}?sid= path probes
POST /api/client?sid= device-measured report (pings, env, webrtc, probes)
POST /api/app?sid= native app report (interfaces, proxy, path)
GET /api/result?sid=[&final=1] verdict JSON (final=1 wipes the session)
UDP :3479 "PLK1 <sid> <tag>" raw UDP echo
UDP :3478 STUN binding
How it works
One Go program runs on one server. It answers DNS for the test domain itself, so it sees every resolver that queries it. It captures the first packet (SYN) of incoming connections for fingerprinting, and reads the kernel's TCP stats for each connection. It runs its own STUN server and UDP echo port. It serves HTTPS and HTTP/3 with a Let's Encrypt certificate.
| Port | Purpose |
|---|---|
| tcp 80 / 443 | Page + API · HTTPS (h2) + HTTP/3 on udp 443 |
| tcp 8080 / 8443 | Alternate-port route test; TCP-only latency pings |
| udp+tcp 53 | Authoritative DNS for the test zone |
| udp 3478 / 3479 | STUN · raw UDP echo |