How to Fix a WebRTC Leak in Chrome, Firefox and Safari

Blog / IP & privacy

How to Fix a WebRTC Leak in Chrome, Firefox and Safari

To stop a WebRTC leak: in Firefox, adjust the media.peerconnection settings in about:config. In Chrome, install Google's official WebRTC Network Limiter extension, or restrict WebRTC with the enterprise policy WebRtcIPHandling. Safari is already fairly locked down by default and usually needs no changes. After you change anything, open cdnping's IP and environment check and look at the WebRTC row to see whether any address you wanted to hide is still visible.

Why WebRTC leaks your IP

WebRTC is the browser API for real-time audio, video and peer-to-peer transfer. For two ends to connect directly, the browser first gathers the network addresses it can use. These are called ICE candidates, and there are three main types:

  • host: addresses on your local network interfaces, such as a private address like 192.168.1.23, or a public IPv6 address.
  • srflx (server reflexive): the source address a STUN server sees when the browser sends it a UDP packet. This is your public egress address.
  • relay: the address allocated when traffic goes through a TURN relay server.

Any script on a page can create an RTCPeerConnection and read these candidates, with no permission prompt. That is the problem. Many people use an HTTP or SOCKS browser proxy. Page traffic goes through the proxy, but the UDP packets WebRTC sends to STUN servers may not, so the srflx candidate shows the real egress IP assigned by your local ISP, which doesn't match the proxy IP the page sees. This is what people call a WebRTC leak. A full-tunnel VPN or a system-level transparent proxy normally avoids this, because UDP is captured too, but private addresses and IPv6 addresses in host candidates can still be exposed.

For more background, see DNS leaks and WebRTC leaks. If you use routing rules, also read split tunneling, since WebRTC's UDP traffic may fall outside what your rules cover.

How to check whether you have a WebRTC leak

Record a baseline before you change anything, so you have something to compare against.

  1. Disable unrelated browser extensions and open /ip.
  2. Note the egress IP at the top of the page (the address web requests see).
  3. Find the "WebRTC leak" item and look at the candidate addresses it lists:
    • Only xxxx.local hostnames, or only addresses identical to the egress IP: no leak.
    • A public IPv4 or IPv6 address that differs from the egress IP: a leak. That address is usually your real local egress.
    • Private addresses such as 192.168.*, 10.* or 172.16-31.*: this exposes LAN information. The risk is lower, but you can tighten it too.
  4. On the same page, the "DNS leak" and "Mainland China split-routing check" items are worth a look. They are often different symptoms of the same misconfiguration as the WebRTC leak.

/ip can generate a watermarked result image, and you can hide the IP before generating it, so you don't have to blur it by hand when you paste it into a ticket or a chat. The browser fingerprint on the page is computed locally and is not uploaded.

Firefox: about:config settings

Firefox has the most tunable options of the three. Type about:config in the address bar, accept the risk warning, and search for media.peerconnection.

SettingRecommended valueEffect
media.peerconnection.enabledfalseTurns WebRTC off entirely. The most thorough option, but all in-browser audio and video calls stop working
media.peerconnection.ice.default_address_onlytrueUses only the address on the default route instead of enumerating every network interface
media.peerconnection.ice.no_hosttrueDoesn't expose host candidates (local interface addresses)
media.peerconnection.ice.proxy_only_if_behind_proxytrueWhen a proxy is configured, WebRTC goes through the proxy only and doesn't send UDP directly
media.peerconnection.ice.relay_onlytrueUses TURN relays only, with no direct connections (the web app itself must provide TURN)

Two common approaches:

  • You don't need in-browser calls: just set media.peerconnection.enabled to false and leave the rest alone.
  • You still need web meetings: keep enabled = true and set default_address_only, no_host and proxy_only_if_behind_proxy to true. Most meetings still connect, and UDP no longer bypasses the proxy.

To configure several machines the same way, put the settings in a user.js file in the profile directory, which Firefox reads on every start:

// user.js, placed in the Firefox profile directory (about:profiles shows the path)
user_pref("media.peerconnection.ice.default_address_only", true);
user_pref("media.peerconnection.ice.no_host", true);
user_pref("media.peerconnection.ice.proxy_only_if_behind_proxy", true);
// Uncomment the next line only if you never use WebRTC
// user_pref("media.peerconnection.enabled", false);

Restart the browser after changing these, then go back to /ip and retest.

Chrome: official extension or enterprise policy

Chrome has no setting that turns WebRTC off. Since fairly early versions, Chrome by default replaces private addresses in host candidates with random .local hostnames (mDNS), so your private IP is usually already hidden. What's left to handle is mainly the public address in srflx. There are two routes.

Option 1: the WebRTC Network Limiter extension

This is the official extension Google publishes in the Chrome Web Store, and it suits personal computers.

  1. Search the Chrome Web Store for "WebRTC Network Limiter", confirm the publisher is Google, and install it.
  2. Open the extension's options page.
  3. Pick a routing mode that fits your needs. To keep traffic from bypassing your proxy, choose an option like "Use my proxy server (if present)", which means proxy only, with non-proxied UDP disabled.
  4. Restart the browser and retest on /ip.

The wording of the options changes between versions, so use "does it allow UDP that doesn't go through the proxy" as your test when choosing.

Option 2: the WebRtcIPHandling enterprise policy

If you manage a team's browsers, or prefer not to depend on an extension, Chrome's enterprise policy is more reliable. The policy is called WebRtcIPHandling, with these values:

ValueMeaningWhen to use
defaultDefault behavior, can use all network interfacesNo restriction
default_public_and_private_interfacesUses only the public and private interfaces on the default routeMulti-NIC machines, to reduce enumeration
default_public_interface_onlyUses only the public interface on the default route and doesn't expose private addressesYou only care about private addresses
disable_non_proxied_udpBlocks UDP that doesn't go through the proxy. WebRTC can only use the proxy (falling back to TCP if the proxy doesn't support UDP, or failing to connect)Preventing public IP leaks when using a browser proxy

How to set it on each platform:

# Linux (Chrome), requires root
sudo mkdir -p /etc/opt/chrome/policies/managed
echo '{ "WebRtcIPHandling": "disable_non_proxied_udp" }' | \
  sudo tee /etc/opt/chrome/policies/managed/webrtc.json
# For Chromium the path is /etc/chromium/policies/managed/
# Windows, administrator PowerShell
New-Item -Path "HKLM:\SOFTWARE\Policies\Google\Chrome" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Google\Chrome" `
  -Name "WebRtcIPHandling" -Value "disable_non_proxied_udp" -Type String

On macOS, the proper way is to push WebRtcIPHandling in the com.google.Chrome domain through a configuration profile (MDM). On a personal machine you can try defaults write com.google.Chrome WebRtcIPHandling -string disable_non_proxied_udp first, but Chrome doesn't always treat that as a mandatory policy, so trust the retest result.

After writing the policy, open chrome://policy in the address bar, click "Reload policies", and confirm WebRtcIPHandling appears with a normal status. If you also want to limit the local UDP port range WebRTC uses, you can set WebRtcUdpPortRange separately. It isn't directly related to leaks, so decide based on your network administration needs.

Chromium-based browsers such as Edge and Brave have equivalent policies or settings. Check each browser's official documentation for the names and paths.

Does Safari need changes?

Safari's default policy is conservative. Until a page has been granted camera or microphone access, Safari doesn't expose local interface addresses to scripts as host candidates. So a private-address leak generally doesn't happen in Safari.

Two things to watch:

  • Once you grant a site camera or microphone access, that site may get more candidate addresses. Under "Safari Settings → Websites → Camera / Microphone" you can check which sites are set to "Allow" and change the ones you don't need to "Ask" or "Deny".
  • Safari has no user-facing switch to turn WebRTC off. The Develop menu (Settings → Advanced → Show features for web developers) has WebRTC debugging options, and the one that relaxes ICE candidate restrictions exposes more. Leave it unchecked for everyday use.

If you use a browser-level proxy in Safari rather than a system VPN, the srflx candidate may still show your local egress. A more reliable fix is to switch to a system-level proxy or VPN so UDP is captured as well, then retest on /ip.

Will web meetings still work after restricting WebRTC?

The cost of restricting WebRTC falls on browser-based audio and video apps, such as video meetings opened in the browser, web customer-support calls and real-time collaboration on online whiteboards. Desktop clients aren't affected by browser settings.

SettingWeb meetings work?Possible symptoms
Firefox media.peerconnection.enabled = falseNoThe page says the browser isn't supported, or hangs on "Connecting"
Firefox no_host / default_address_onlyUsuallyA call between two people on the same LAN may go over the public network instead, with slightly higher latency
Firefox relay_only / Chrome disable_non_proxied_udpDepends on the serviceTraffic goes through a TURN relay or the proxy, so latency and packet loss go up. If the proxy doesn't forward UDP and the service has no TCP fallback, the call won't connect
Chrome default_public_interface_onlyUsuallyBarely noticeable
Safari defaultYesWorks normally once camera access is granted

If you only join web meetings occasionally, an easy approach is to lock down your everyday browser profile and keep a separate profile with unchanged settings just for meetings (a Chrome user profile, or a Firefox profile via about:profiles).

Confirming the fix

Run through this in order:

  • The browser has been restarted, and in Chrome the policy shows as active in chrome://policy.
  • In the WebRTC row on /ip, there is no public address different from the egress IP.
  • IPv6 has been checked too: in the IPv4/IPv6 check on the same page, if you have local IPv6 and your proxy doesn't support it, WebRTC may expose the IPv6 address on its own.
  • The DNS leak row doesn't show your local ISP's resolvers.
  • You've tried your usual web meeting once and confirmed it connects.
  • If you need a record, generate a result image on /ip and turn on "Hide IP" before sharing it.

Disclosure: AGI Plan is a commercial partner of cdnping. /ip is a tool for developers to check their own network egress, and it doesn't require a login.

These settings are meant to protect your personal network information. Online services have their own terms about the regions and ways they can be accessed. Please follow their terms of service and local laws. This article does not cover how to bypass a platform's regional restrictions or risk controls.

Next steps

  • Open /ip and run a full check, comparing the WebRTC, DNS and Mainland China split-routing results side by side.
  • If WebRTC looks fine but DNS has a problem, continue with the DNS section of DNS leaks and WebRTC leaks.
  • To confirm the type of your egress IP (datacenter, residential, mobile) and who it belongs to, see native IP vs. broadcast IP.
  • After a network change, if you want to see whether latency to the major AI APIs has changed, run a round of the online speed test on the homepage.

Related articles

Keep reading