Disabling WebRTC is suspicious if it means deleting the API. Every Chrome people actually run defines RTCPeerConnection, so a page that looks for it and finds nothing has learned that this browser was modified, which is more than a leak would have told it. Keeping the API and letting it gather zero candidates is different: that is what any machine on a network that blocks UDP reports. We found this out by measuring our own "disabled" option, which turned out to do neither.
What our "disabled" option was doing
Mosaic's profile editor has a WebRTC field with three choices. One of them used to be labelled "No RTCPeerConnection at all". The deletion behind that label lived in an injected script. On our own engine, Tesseract Chrome, the injection is switched off wholesale, because fingerprint values there are changed in C++ and never in page JavaScript. So the label promised a deletion that never ran.
We measured it through the leak test, on our engine, with the profile set to disabled:
webrtc: 'disabled' 2 candidates: an mDNS host candidate and
srflx carrying the host's real public address
leak test fail: "set to disabled but still produced 2 candidates"
The leak test had been right all along. Nobody had run it on that setting.
It was worse than inert. Choosing disabled also turned off the engine's own handling of the local address for WebRTC. So the most protective-sounding choice in the list was the least protective one, and it was the one a careful person would pick.
Every profile is drawn from one real computer, not from separate listsIn Mosaic: Machines that exist. GPU, screen, CPU and fonts from one real device. Free holds 3 profiles. Pro is $49 a month for any number.
Mosaic is a desktop app
Email yourself the link and open it on your computer.
How it works: Machines that exist
Two of the three flags were not switches
While we were there, we checked every WebRTC flag Mosaic sent against the binaries themselves, with strings, on our engine, a fork we compared with, and the machine's own Google Chrome:
webrtc-ip-handling-policy ours 1 fork 2 stock 2
force-webrtc-ip-handling-policy ours 0 fork 0 stock 0
webrtc-ip ours 0 fork 0 stock 0
Chromium accepts a switch it does not know without a word, so both of the missing ones had been passed at every launch and done nothing. The second mattered most. --webrtc-ip was the whole implementation of the editor's "Replace with proxy IP". Nothing replaced anything, on any engine, for as long as that option existed.
Nothing replaces it now either, because there is nothing for it to do. A server-reflexive candidate is whatever address the STUN packet left from. What protects a proxied profile is that no candidate is gathered around the proxy in the first place.
Is disabling WebRTC suspicious? Only if the constructor goes
The one real flag was enough. We ran the same probe in a fresh profile folder per row, no proxy, on our engine and on Google Chrome:
ours Google Chrome
no policy RTC present, 2 RTC present, 2
disable_non_proxied_udp RTC present, 0 RTC present, 0
Both browsers agree, which is the point. With the policy set, RTCPeerConnection is still a function a page can call, a peer connection can still be built, and gathering simply finishes with nothing. A page cannot tell that apart from an office network, a hotel or a mobile carrier that drops UDP. A missing constructor has no such crowd to hide in.
So "disabled" now means the policy switch, sent on every engine. The injected deletion is gone. The option is labelled "Gather nothing", with the hint "WebRTC stays present and produces no candidates", and on the leak test it went from 2 candidates and a fail to 0 and a pass. Any profile with a proxy attached gets the same policy by default, so no candidate escapes around the proxy.
We also took out something the old branch did quietly: it refused getUserMedia, the camera and microphone call. That belongs to a different setting, and one switch silently deciding another is how settings stop meaning what they say.
The leak report erred in the flattering direction
The leak test is the one screen people trust instead of measuring, so a wrong line there costs more than a missing one. It had three, and all of them flattered the profile:
- With no proxy attached, it called the machine's own public address "the proxy exit".
- It reported "WebRTC exposed 0.0.0.0" for a candidate carrying
raddr 0.0.0.0, which is what Chrome writes when it withholds the local address. The protection working was reported as a leak. - It told an unproxied profile to "run a proxy check first", when there was no proxy to check.
The cause of the first and third was one value doing two jobs: an empty proxy address meant both "no proxy" and "proxy never checked". The report now gets those as separate facts, and a build check covers each of the three, proved by putting the fault back and watching the right assertion fail.
Reading your own result
A .local host candidate is Chrome hiding your private address, not a leak; the mDNS post explains why we leave it on. A server-reflexive candidate that is not your proxy's exit is the real leak. No candidates with RTCPeerConnection defined is the right shape on a proxied profile. And a test that finds no RTCPeerConnection at all is telling you about the browser, not the network.
WebRTC is one surface of a browser fingerprint, and the rule behind this fix is the one behind how Mosaic draws real fingerprints: the right answer is the one a real Chrome would give. The proxy checks worth running before any of this are in how to check a proxy before you use it.




