WebRTC Leak Prevention: Stop IP Leaks in Anti-Detect Browsers

WebRTC Leak Prevention: Stop IP Leaks in Anti-Detect Browsers

WebRTC (Web Real-Time Communication) is a browser technology that enables peer-to-peer audio, video, and data sharing. While useful for video calls and file transfers, WebRTC has a well-known side effect: it can reveal your real IP address even when you are using a proxy or VPN. For anyone running multi-account operations through anti-detect browsers or web scraping through residential proxies, WebRTC leaks can expose your true identity and link your accounts.

How WebRTC Leaks Happen

WebRTC uses ICE (Interactive Connectivity Establishment) to find the best path for peer-to-peer connections. As part of this process, the browser queries STUN (Session Traversal Utilities for NAT) servers to discover its public IP address. This happens at the browser level, bypassing proxy settings.

Normal browsing with proxy:
Browser -> Proxy -> Website (sees proxy IP)

WebRTC STUN request:
Browser -> STUN Server (bypasses proxy, reveals real IP)
Website JavaScript reads ICE candidates -> Gets your real IP

What Gets Leaked

A WebRTC leak can expose:

DataRiskExample
Public IPv4 addressYour real external IP203.0.113.45
Public IPv6 addressOften more identifying2001:db8::1
Local/private IPInternal network info192.168.1.105
VPN/proxy interface IPReveals VPN usage10.8.0.2
mDNS candidatesBrowser-generated UUIDabc123.local

The JavaScript That Exposes You

Websites can extract your IP through WebRTC with simple JavaScript:

// This code can reveal your real IP even behind a proxy
async function getWebRTCIPs() {
    const ips = new Set();
    const pc = new RTCPeerConnection({
        iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
    });

    pc.createDataChannel("");

    pc.onicecandidate = (event) => {
        if (event.candidate) {
            const candidate = event.candidate.candidate;
            // Extract IP from ICE candidate string
            const ipRegex = /([0-9]{1,3}\.){3}[0-9]{1,3}/;
            const match = candidate.match(ipRegex);
            if (match) {
                ips.add(match[0]);
                console.log("Discovered IP:", match[0]);
            }
        }
    };

    const offer = await pc.createOffer();
    await pc.setLocalDescription(offer);

    // Wait for ICE gathering
    await new Promise(resolve => setTimeout(resolve, 3000));
    pc.close();

    return [...ips];
}

Testing for WebRTC Leaks

Before relying on your anti-detect browser or proxy setup, test for leaks:

Manual Testing

  1. Visit BrowserLeaks WebRTC test
  2. Check if any IP addresses shown differ from your proxy IP
  3. If you see your real IP or local network IP, you have a leak

Automated Testing

from playwright.async_api import async_playwright
import asyncio

async def check_webrtc_leak(browser_ws=None):
    """Test for WebRTC leaks in a browser profile."""
    async with async_playwright() as p:
        if browser_ws:
            browser = await p.chromium.connect_over_cdp(browser_ws)
        else:
            browser = await p.chromium.launch()

        page = await browser.new_page()

        # Get proxy IP first
        await page.goto("https://httpbin.org/ip")
        proxy_ip = await page.evaluate("document.body.innerText")

        # Now check WebRTC IPs
        await page.goto("about:blank")
        webrtc_ips = await page.evaluate("""
        async () => {
            return new Promise((resolve) => {
                const ips = [];
                const pc = new RTCPeerConnection({
                    iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
                });
                pc.createDataChannel('');
                pc.onicecandidate = (e) => {
                    if (e.candidate) {
                        const match = e.candidate.candidate.match(
                            /([0-9]{1,3}\\.){3}[0-9]{1,3}/
                        );
                        if (match) ips.push(match[0]);
                    }
                };
                pc.createOffer().then(o => pc.setLocalDescription(o));
                setTimeout(() => {
                    pc.close();
                    resolve([...new Set(ips)]);
                }, 5000);
            });
        }
        """)

        print(f"Proxy IP: {proxy_ip}")
        print(f"WebRTC IPs: {webrtc_ips}")

        # Check for leaks
        import json
        proxy_ip_clean = json.loads(proxy_ip)["origin"]
        leaked = [ip for ip in webrtc_ips if ip != proxy_ip_clean
                  and not ip.startswith("192.168.")
                  and not ip.startswith("10.")
                  and not ip.startswith("0.")]

        if leaked:
            print(f"WARNING: WebRTC LEAK DETECTED! Leaked IPs: {leaked}")
        else:
            print("OK: No WebRTC leak detected")

        await browser.close()

asyncio.run(check_webrtc_leak())

Prevention Methods

Method 1: Disable WebRTC Entirely

The most secure approach, but may break video calling and some website features:

Chrome/Chromium:

# Launch flag
chrome --disable-features=WebRtcHideLocalIpsWithMdns \
       --enforce-webrtc-ip-permission-check

Firefox:

# In about:config
media.peerconnection.enabled = false

Playwright/Puppeteer:

# Playwright
browser = await p.chromium.launch(
    args=[
        "--disable-features=WebRtcHideLocalIpsWithMdns",
        "--enforce-webrtc-ip-permission-check",
        "--webrtc-ip-handling-policy=disable_non_proxied_udp",
    ]
)

# Puppeteer
const browser = await puppeteer.launch({
    args: [
        '--disable-features=WebRtcHideLocalIpsWithMdns',
        '--enforce-webrtc-ip-permission-check',
    ]
});

Method 2: WebRTC IP Handling Policy

Chrome supports a policy that controls which IPs WebRTC can use:

# Chrome launch options
WEBRTC_POLICIES = {
    "default": "default",
    "default_public_and_private": "default_public_and_private_interfaces",
    "default_public": "default_public_interface_only",
    "disable_non_proxied": "disable_non_proxied_udp",
}

# Most restrictive - forces WebRTC through proxy
browser = await p.chromium.launch(
    args=["--webrtc-ip-handling-policy=disable_non_proxied_udp"]
)
PolicyLocal IPsPublic IPProxiedSecurity
defaultExposedExposedNoNone
default_public_and_privateExposedExposedNoNone
default_publicHiddenExposedNoMedium
disable_non_proxied_udpHiddenHiddenYesHigh

Method 3: JavaScript Override

Inject a script that modifies WebRTC behavior before any fingerprinting runs:

// Inject before page loads to prevent WebRTC leaks
(function() {
    // Option A: Block RTCPeerConnection entirely
    // window.RTCPeerConnection = undefined;

    // Option B: Override to filter candidates (better compatibility)
    const OriginalRTC = window.RTCPeerConnection ||
                        window.webkitRTCPeerConnection ||
                        window.mozRTCPeerConnection;

    if (!OriginalRTC) return;

    window.RTCPeerConnection = function(config, constraints) {
        // Remove STUN servers to prevent IP discovery
        if (config && config.iceServers) {
            config.iceServers = config.iceServers.filter(
                server => !server.urls.toString().includes('stun:')
            );
        }

        const pc = new OriginalRTC(config, constraints);

        // Override onicecandidate to filter out real IPs
        const originalSetOnIce = Object.getOwnPropertyDescriptor(
            RTCPeerConnection.prototype, 'onicecandidate'
        );

        // Additional filtering logic here

        return pc;
    };

    window.RTCPeerConnection.prototype = OriginalRTC.prototype;
})();

Method 4: Anti-Detect Browser Settings

Each major anti-detect browser handles WebRTC differently:

Multilogin:

  • Settings > WebRTC > “Altered” (replaces real IP with proxy IP)
  • Can also set to “Disabled” or “Real”
  • Recommended: “Altered” for most use cases

GoLogin:

  • Profile settings > WebRTC > “Altered” or “Disabled”
  • Automatically matches WebRTC IP to proxy

AdsPower:

  • Fingerprint settings > WebRTC > Choose policy
  • Options: Real, Replace, Disabled

Dolphin Anty:

  • Profile > WebRTC > “Altered” mode
  • Shows proxy IP instead of real IP

Best Configuration per Use Case

Use CaseWebRTC SettingWhy
Social media accountsAlteredVideo calls may be needed
Web scrapingDisabledNo need for WebRTC
E-commerce managementAlteredSome sites check WebRTC
Streaming accessAlteredWebRTC needed for some players
Ad verificationDisabledPure data collection

Common Mistakes

  1. Forgetting IPv6 — Even if IPv4 is protected, IPv6 may leak. Disable IPv6 or ensure it is also proxied.
  1. Testing only once — WebRTC behavior can differ between pages on the same site. Test multiple scenarios.
  1. Browser extensions conflict — Some extensions re-enable WebRTC or override your anti-detect settings. Minimize extension usage.
  1. mDNS false sense of security — Modern Chrome uses mDNS candidates (UUIDs like abc123.local) instead of real IPs. This is better but still has edge cases where real IPs can be exposed through STUN.
  1. Ignoring TURN servers — STUN gets most attention, but TURN servers with authentication can also be used to discover your IP.

FAQ

Does disabling WebRTC break websites?

Most websites work fine without WebRTC. You will lose video/audio calling functionality (Google Meet, Zoom web client, Discord in browser) and some peer-to-peer file sharing features. For web scraping and account management, disabling WebRTC has minimal impact.

Can websites detect that I disabled WebRTC?

Yes. A website can check for the existence of RTCPeerConnection in the JavaScript API. If it is undefined, that signals privacy tooling. The “altered” mode in anti-detect browsers is better because WebRTC still appears functional but returns the proxy IP instead of your real IP.

Is WebRTC the only way websites can discover my real IP?

No. DNS leaks, HTTP headers (like X-Forwarded-For), and even timing attacks can reveal your real IP. WebRTC is the most common vector, but comprehensive protection requires proper proxy configuration and DNS leak prevention.

Do mobile browsers have WebRTC leaks?

Yes. Mobile Chrome and Firefox support WebRTC and can leak IPs the same way desktop browsers do. Mobile anti-detect profiles should also have WebRTC protection configured.

How do I verify my anti-detect browser prevents WebRTC leaks?

After configuring your profile with a proxy and WebRTC protection, visit browserleaks.com/webrtc. You should see only your proxy’s IP address (or no IPs if WebRTC is disabled). Run this check for every new profile before using it for sensitive operations.


Related Reading

Scroll to Top