# How to check a proxy for IP, DNS and WebRTC leaks with ToDetect

Source: https://ipvolt.com/blog/proxy-leak-check-todetect
Markdown: https://ipvolt.com/blog/proxy-leak-check-todetect.md

[Home](https://ipvolt.com/index.md) / [Blog](https://ipvolt.com/blog.md) / Check a Proxy for IP, DNS and WebRTC Leaks with ToDetect

Category: Analysis
Published: 2026-10-23
Updated: 2026-10-23
Author: ipvolt
Reading time: 9 minutes
Tags: proxies, troubleshooting

Check a browser proxy for IP, DNS, WebRTC and time zone leaks with ToDetect's free tools, using measured results from a 4G mobile line as the worked example.

A browser proxy changes where page requests come from. DNS lookups, WebRTC connections and the browser's time zone can still point to the machine's own network. This guide shows how to check each one with ToDetect's free tools, what a pass and a fail look like, and which fixes held up in our test.

The worked example is a real test that ipvolt ran:

- **When:** 23 October 2026, 16:45 to 16:57 UTC.
- **Machine:** a Mac running macOS 15.7.4.
- **Browsers:** Chromium 153 and Firefox, driven by Playwright 1.63.0, in headless mode and in normal windows.
- **Proxy:** a 4G mobile proxy on Vodafone Germany that we use for pre-launch testing, set up as an HTTP proxy with a username and password. [Germany proxies](/guides/germany-proxies) covers the German mobile network context.
- **The machine's own connection:** a commercial VPN exit in Tallinn, Estonia, which is a datacenter address.
- **Masking:** IP addresses are masked in the screenshots and removed from the [results file](/downloads/proxy-leak-check-todetect/results.json), which lists the counts and scores from every run.

## 1. Get a baseline without the proxy

Run each test once with the proxy off, so you know what your own connection looks like. Our baseline on [ToDetect's IP Quality Check](https://www.todetect.net/ip/) was: location Tallinn, IP type Datacenter, ASN organization labelled HOSTING, and an IP Quality Score of 68%. The [DNS Leak Test](https://www.todetect.net/dns-leak/) showed one resolver, the VPN's, in Estonia.

## 2. Check the IP the website sees

Turn the proxy on and reload [the IP Quality Check](https://www.todetect.net/ip/). Check four fields against what you expect from the proxy: location, ISP and ASN, IP type, and time zone.

Through the mobile proxy, the page showed Berlin, ISP D2VODAFONE, ASN 3209 (Vodafone GmbH), IP type Mobile, IP Abuse "No", time zone Europe/Berlin and language German.

![ToDetect IP Quality Check through the mobile proxy: Berlin, D2VODAFONE, IP type Mobile, IP Quality Score 94%](/media/blog/proxy-leak-check-todetect/leak-ip.png)
*ToDetect IP Quality Check through the 4G test line, 23 October 2026. IP address and prefix masked.*

The score is built from listed deductions, and you can open them to see why it changed:

| Connection | IP type | Score | Deductions shown |
| --- | --- | ---: | --- |
| Machine's own (VPN, Estonia) | Datacenter | 68% | IP Usage Frequency -3%, VPS/IDC Provider -25%, Occasional ASN Organization Change -4% |
| 4G mobile proxy (Vodafone Germany) | Mobile | 94% | IP Usage Frequency -3%, Regional ISP -3% |

Most of the gap is the VPS/IDC Provider deduction. A pass means the location, ISP and IP type match the proxy you configured; step 5 compares the time zone with the browser. If you still see your own ISP or city, the browser is not using the proxy, and the other tests will not mean much until that is fixed. The score reflects ToDetect's own databases; treat it as one signal.

## 3. Check where DNS is resolved

Run [the DNS Leak Test](https://www.todetect.net/dns-leak/) with the proxy on. It lists the DNS resolvers that answered lookups for your browser. A pass is a resolver list that belongs to the proxy's network or a resolver you chose on purpose. A fail is your own ISP's or your own network's resolver.

Through the proxy, the resolvers were 139.7.74.9 and 139.7.74.10, both "Vodafone Germany, Germany". The Estonian resolver from the baseline was gone.

![ToDetect DNS Leak Test through the proxy: two Vodafone Germany resolvers](/media/blog/proxy-leak-check-todetect/leak-dns-leak.png)
*Both resolvers belong to Vodafone Germany. The client IP at the top is masked.*

This is expected for an HTTP proxy in Chromium, whose documentation says "name resolution is always deferred to the proxy": the hostname travels in the CONNECT request. DNS leaks can happen with SOCKS4, or with SOCKS5 clients that resolve names locally before connecting, such as curl with `socks5://` rather than `socks5h://`. [SOCKS5 vs SOCKS5h](/blog/socks5-vs-socks5h) covers that case.

## 4. Check WebRTC

Open [the WebRTC Leak Test](https://www.todetect.net/webrtc/). It asks 17 STUN servers which public address your browser appears to come from. A pass is "Not detected" or the proxy's address for every server. A fail is the red "WebRTC IP Exposure Detected" banner and your own address in the Public IP fields.

With default settings, both browsers failed:

- **Chromium, default:** 13 of 17 STUN servers returned the machine's own address (11 or 12 as IPv4, 1 or 2 as IPv6, across three runs). The other 4 showed "Not detected".
- **Firefox, default:** 10 of 17 returned the machine's own IPv4 address and 4 showed "Not detected". The other 3 showed 0.0.0.0, which revealed neither IP; we did not determine why.

![ToDetect WebRTC Leak Test with default Chromium settings: WebRTC IP Exposure Detected](/media/blog/proxy-leak-check-todetect/leak-webrtc.png)
*The page places the connection in Berlin, from the proxy's IP, but STUN servers returned the machine's own address (masked): 13 of 17 in this run. The crop shows three.*

The reason is the transport. WebRTC sends STUN requests over UDP. A standard HTTP proxy relays only TCP connections, so by default those requests go out over the machine's own connection, and the STUN server sees that public IP. RFC 8828 describes this case: if direct Internet access is permitted, "WebRTC's STUN checks will bypass the proxy and reveal the public IP address of the client."

### Fixes we tested

| Browser and setting | STUN servers showing the machine's own address | Result |
| --- | ---: | --- |
| Chromium, default | 13 of 17 (three runs) | Leak |
| Chromium headless, `--force-webrtc-ip-handling-policy=disable_non_proxied_udp` | 0 of 17 (one run) | Pass |
| Chromium in a normal window, same flag | 13 of 17 (two runs) | Leak |
| Chromium in a normal window, profile preference `webrtc.ip_handling_policy` = `disable_non_proxied_udp` | 0 of 17 (two runs) | Pass |
| Firefox, default | 10 of 17 (one run) | Leak |
| Firefox, `media.peerconnection.ice.proxy_only` = true | 0 of 17 (one run) | Pass |

*Counts include both IPv4 and IPv6 addresses.*

The command-line flag fixed headless Chromium but not a normal window. Chromium's source reads the switch in the headless shell, while normal Chrome reads the `webrtc.ip_handling_policy` profile preference. We found no documentation saying the flag is ignored in a normal window, so treat this as a measured result, not a documented rule.

The Chromium fix we measured writes the preference into the profile's `Default/Preferences` file before launch. In Playwright, that needs a persistent context:

```js
import { chromium } from 'playwright';
import { mkdtempSync, mkdirSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';

const dir = mkdtempSync(join(tmpdir(), 'leak-check-'));
mkdirSync(join(dir, 'Default'));
writeFileSync(
  join(dir, 'Default', 'Preferences'),
  JSON.stringify({ webrtc: { ip_handling_policy: 'disable_non_proxied_udp' } }),
);

const context = await chromium.launchPersistentContext(dir, {
  headless: false,
  proxy: {
    server: process.env.PROXY_SERVER,
    username: process.env.PROXY_USERNAME,
    password: process.env.PROXY_PASSWORD,
  },
});
```

`PROXY_SERVER` holds the proxy URL, including the scheme and port. [Playwright proxy setup](/guides/playwright-proxy-setup) covers the rest of the client configuration.

Two other ways to set the same preference in Chrome, which we did not test:

- Set the [WebRtcIPHandling](https://chromeenterprise.google/policies/#WebRtcIPHandling) enterprise policy to `disable_non_proxied_udp`. Chrome then uses UDP only if the configured proxy supports it, and otherwise uses TCP through the proxy. The policy page gives the Windows registry location and the macOS and Linux preference name.
- Install Google's [WebRTC Network Limiter](https://chromewebstore.google.com/detail/webrtc-network-limiter/npeicpdbkakmehahjeeohfdhnlpdklia) extension. Its store listing says disabling non-proxied UDP is off by default and is turned on from the Options page.

According to Chromium's policy definition and the `chrome.privacy` documentation, both control the preference we set. Rerun the WebRTC test after applying either.

In Firefox, open `about:config` and set `media.peerconnection.ice.proxy_only` to `true`, so WebRTC traffic goes only through the configured proxy. In Playwright, pass it as `firefoxUserPrefs: { 'media.peerconnection.ice.proxy_only': true }` to `firefox.launch()`. Setting `media.peerconnection.enabled` to `false` turns WebRTC off entirely. We tested only the first setting, without the time zone options from step 5.

![ToDetect WebRTC Leak Test after the fix: every STUN server shows Not detected](/media/blog/proxy-leak-check-todetect/fixed-webrtc.png)
*Chromium in a normal window with the profile preference: no exposure banner, all 17 servers "Not detected" (three shown).*

## 5. Check the time zone

Open [the Timezone Detection page](https://www.todetect.net/timezone/). It compares the time zone inferred from your IP with the browser's own time zone ID. If you are checking how a site behaves for visitors in the proxy's location, such as localised pages or ad placements, the two should match.

With the proxy on and the browser left on the machine's settings, the IP-based zone was Europe/Berlin and the browser's IANA time zone ID was Europe/Vilnius. That is a mismatch in the time zone ID. The proxy changes the network path, not the browser's time zone setting. In our run ToDetect showed the same UTC offset for both; only the zone ID differed.

![ToDetect Timezone Detection: IP-based Europe/Berlin vs browser Europe/Vilnius](/media/blog/proxy-leak-check-todetect/leak-timezone.png)
*The IP-based zone follows the proxy. The browser's zone ID stays on the machine's setting.*

In Chromium, we then added `timezoneId: 'Europe/Berlin'` and `locale: 'de-DE'` to the `launchPersistentContext()` options from step 4. This combined setup is the one behind the "after" screenshots. Both zones then read Europe/Berlin.

![ToDetect Timezone Detection after the change: both zones Europe/Berlin, locale de-DE](/media/blog/proxy-leak-check-todetect/fixed-timezone.png)
*After the change: the browser's IANA time zone ID is Europe/Berlin and the locale is de-DE.*

In a normal browser without automation, the time zone comes from the operating system: change the system time zone and set the language in the browser's settings. We did not test this route, so recheck the page afterwards.

## 6. Read the fingerprint overview last

[ToDetect's homepage](https://www.todetect.net/) combines the checks above into a "Browser Fingerprint Consistency" score, which ToDetect says "does not represent a definitive pass or fail result". In a normal Chromium window with a persistent profile, it showed 65% with default settings and 87% after the WebRTC and time zone changes, as displayed. The Timezone Anomaly and WebRTC Alert deductions were gone. The WebDriver and ClientRect deductions that remained come from the automated test browser; a Language Anomaly also remained, and we did not establish what triggered it.

The [Bot Detection page](https://www.todetect.net/bot-detection/) flagged WebDriver and Dev Tool anomalies in every run, and a Headless Chrome anomaly in the headless runs, which is expected for automation. Private-style contexts and headless mode added fingerprint deductions of their own, so for QA, ad verification or geo checks, test in the browser profile you will use for the real work.

## What we did not test

We did not test SOCKS5 in the browser (Chromium does not support username/password login to SOCKS5 proxies), Safari, Edge, mobile browsers or IP rotation during a session. These results describe one line, one machine and one day.

## Checklist

1. Record a baseline with the proxy off: IP, ISP, IP type and DNS resolvers.
2. With the proxy on, confirm the [IP check](https://www.todetect.net/ip/) shows the proxy's location, ISP and IP type, not yours.
3. Confirm the [DNS Leak Test](https://www.todetect.net/dns-leak/) lists only the proxy network's resolvers or ones you chose.
4. Run the [WebRTC Leak Test](https://www.todetect.net/webrtc/). If your own address appears, set Chrome's `webrtc.ip_handling_policy` preference to `disable_non_proxied_udp` or Firefox's `media.peerconnection.ice.proxy_only` to `true`, then rerun it. Do not rely on the command-line flag in a normal window.
5. If your test depends on the proxy's location, match the browser's time zone and locale to it (Playwright options, or the system time zone and browser language in a normal browser), then recheck [Timezone Detection](https://www.todetect.net/timezone/).
6. Read the fingerprint deductions, separating those caused by the proxy from those caused by your test setup.
7. Rerun every test after any change, in the browser setup you will actually use.

ipvolt ran these checks for its own pre-launch testing. The service is in development and access opens in early November. If you want to hear when it does, [join the early-access list](https://ipvolt.com/#waitlist-closing). One email when access opens. Nothing else.

## Sources

- [Chromium: Proxy support in Chrome (net/docs/proxy.md)](https://chromium.googlesource.com/chromium/src/+/main/net/docs/proxy.md)
- [RFC 8828: WebRTC IP Address Handling Requirements](https://www.rfc-editor.org/rfc/rfc8828)
- [Chrome Enterprise policy: WebRtcIPHandling](https://chromeenterprise.google/policies/#WebRtcIPHandling)
- [Chromium policy definition: WebRtcIPHandling.yaml](https://chromium.googlesource.com/chromium/src/+/main/components/policy/resources/templates/policy_definitions/WebRtc/WebRtcIPHandling.yaml)
- [Chrome extensions API: chrome.privacy (webRTCIPHandlingPolicy)](https://developer.chrome.com/docs/extensions/reference/api/privacy)
- [Chrome Web Store: WebRTC Network Limiter](https://chromewebstore.google.com/detail/webrtc-network-limiter/npeicpdbkakmehahjeeohfdhnlpdklia)
- [Chromium source: content_switches.cc (force-webrtc-ip-handling-policy)](https://chromium.googlesource.com/chromium/src/+/main/content/public/common/content_switches.cc)
- [Chromium source: headless_web_contents_impl.cc](https://chromium.googlesource.com/chromium/src/+/main/headless/lib/browser/headless_web_contents_impl.cc)
- [Chromium source: renderer_preferences_util.cc](https://chromium.googlesource.com/chromium/src/+/main/chrome/browser/renderer_preferences_util.cc)
- [Firefox source: modules/libpref/init/all.js (media.peerconnection prefs)](https://github.com/mozilla-firefox/firefox/blob/main/modules/libpref/init/all.js)
- [Firefox source: StaticPrefList.yaml](https://github.com/mozilla-firefox/firefox/blob/main/modules/libpref/init/StaticPrefList.yaml)
- [ToDetect IP Quality Check](https://www.todetect.net/ip/)
- [ToDetect DNS Leak Test](https://www.todetect.net/dns-leak/)
- [ToDetect WebRTC Leak Test](https://www.todetect.net/webrtc/)
- [ToDetect Timezone Detection](https://www.todetect.net/timezone/)
- [ToDetect Browser Fingerprint Checker](https://www.todetect.net/)
- [ToDetect Bot Detection](https://www.todetect.net/bot-detection/)

## Know when ipvolt access opens.

ipvolt is in development. Leave your email and we’ll notify you once when access opens.

Consent: One email when access opens. Nothing else.

[Notify me](https://ipvolt.com/blog/proxy-leak-check-todetect#waitlist-blog-end). Use the email form on this page to join the interest list.

[Privacy](https://ipvolt.com/privacy)

## Related posts

- [Python 3.15 for Web Scraping: What Installs, What Breaks](https://ipvolt.com/blog/python-3-15-web-scraping.md) (Analysis, Oct 16, 2026, 8 min read): pip install scrapy fails on Python 3.15 without a C compiler: brotli has no cp315 wheel. We tested 19 scraping packages with pip and uv to see what else breaks.
- [Japanese price parsing: yen, width and tax labels](https://ipvolt.com/blog/japanese-price-parsing.md) (Analysis, Oct 6, 2026, 6 min read): Parse Japanese price fields without losing currency or tax basis. Run a tested Python fixture for fullwidth yen, mixed prices and deliberate review cases.
- [SOCKS5 vs SOCKS5h: What 6 Clients Actually Send (Tested)](https://ipvolt.com/blog/socks5-vs-socks5h.md) (Comparison, Oct 4, 2026, 7 min read): socks5:// does not mean local DNS in every client. We logged what curl, Requests, HTTPX, aiohttp, Playwright and Node send a SOCKS5 proxy for each scheme.

## Related guides

- [Configure a proxy in Playwright](https://ipvolt.com/guides/playwright-proxy-setup.md): Set an authenticated HTTP proxy for a Playwright browser context, keep test state isolated, and diagnose navigation separately from subresources.
- [Germany proxies: networks, cities and regional checks](https://ipvolt.com/guides/germany-proxies.md): Evaluate Germany proxies with current carrier and roaming context, city-location limits, browser-language controls and a practical acceptance checklist.
- [HTTP vs SOCKS5 proxies: choose by the connection](https://ipvolt.com/guides/http-vs-socks5-proxies.md): Compare HTTP CONNECT and SOCKS5, understand DNS placement and TLS boundaries, and select a protocol your actual client and provider support.

## About ipvolt

Technical analysis from the ipvolt team.

ipvolt access is not open yet.
