Block WebRTC Leak in Chrome: A Developer’s Guide
WebRTC (Web Real-Time Communication) enables peer-to-peer audio, video, and data sharing directly in browsers. While powerful, it presents a privacy risk: WebRTC can expose your real IP address even when using a VPN or proxy. This guide covers practical methods to block WebRTC leaks in Chrome for developers and power users.
Understanding WebRTC Leaks
When you connect to a website, your browser typically reveals only the IP address associated with your VPN or proxy tunnel. However, WebRTC uses Interactive Connectivity Establishment (ICE) protocols that discover multiple network paths—including your actual local and public IP addresses.
How the Leak Occurs
WebRTC implements the STUN (Session Traversal Utilities for NAT) protocol, which allows servers to request your public IP address from your browser. The browser responds with both the VPN IP and your real IP, bypassing the VPN tunnel entirely.
To see this in action, visit a WebRTC leak test site with your VPN active. You’ll likely see two IP addresses: one from your VPN and another revealing your actual network.
Methods to Block WebRTC Leaks
Method 1: Chrome Flags (Quickest Solution)
Chrome provides a built-in flag to disable WebRTC entirely:
- Open
chrome://flags/#enable-webrtc - Set “WebRTC Stun origin trial” to Disabled
- Restart Chrome
This disables WebRTC globally, breaking any site that relies on peer-to-peer communication.
Method 2: Browser Extensions
Several extensions block WebRTC leaks by intercepting STUN requests:
WebRTC Control (recommended):
- Install from Chrome Web Store
- Click the extension icon to toggle WebRTC on/off
- Provides per-site control
uBlock Origin:
- Enable “Block WebRTC” in settings
- Blocks STUN requests via network filtering
Extensions work well for non-developers but may be bypassed by determined scripts.
Method 3: Chrome Policies (For IT Administrators)
Enterprise environments can enforce WebRTC blocking via Chrome policies:
Windows (Group Policy):
{
"WebRTCIPHandlingPolicy": "disable_non_proxied_udp"
}
macOS (plist):
<key>WebRTCIPHandlingPolicy</key>
<string>disable_non_proxied_udp</string>
Apply via Chrome Enterprise policy templates or MDM solutions.
Method 4: Firefox as Alternative
If WebRTC blocking in Chrome proves unreliable, Firefox offers more granular control:
- Navigate to
about:config - Search for
media.peerconnection.enabled - Set to false
Firefox also supports the media.peerconnection.turn.disable boolean to disable TURN relay usage.
Developer Implementation: Detecting and Handling WebRTC
For developers building privacy-conscious applications, detecting WebRTC leaks in your own code matters.
Detecting WebRTC Support
function isWebRTCSupported() {
return !!(window.RTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.mozRTCPeerConnection);
}
Preventing IP Leakage in Your Application
// Disable WebRTC before establishing connections
function disableWebRTC() {
if (window.RTCPeerConnection) {
window.RTCPeerConnection = function(pcConfig) {
console.log('WebRTC blocked - not creating peer connection');
return null;
};
}
// Override STUN servers to return no results
const originalCreateOffer = RTCPeerConnection.prototype.createOffer;
RTCPeerConnection.prototype.createOffer = function() {
this._iceServers = [];
return originalCreateOffer.apply(this, arguments);
};
}
Testing for Leaks
Build a simple STUN test:
async function testWebRTCLeak() {
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
return new Promise((resolve) => {
pc.onicecandidate = (ice) => {
if (ice.candidate) {
console.log('ICE Candidate:', ice.candidate.candidate);
pc.close();
resolve(ice.candidate.candidate);
}
};
});
}
Detailed Leak Detection with Categorized Results
For a more comprehensive detection function that separates local, public, and IPv6 addresses:
function detectWebRTCLeak() {
const results = { localIP: [], publicIP: [], ipv6: [] };
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('');
pc.createOffer().then(offer => pc.setLocalDescription(offer));
pc.onicecandidate = (ice) => {
if (ice.candidate) {
const candidate = ice.candidate.candidate;
const ipMatch = candidate.match(/(\d{1,3}\.){3}\d{1,3}/);
if (ipMatch) {
const ip = ipMatch[0];
if (ip.startsWith('192.168.') || ip.startsWith('10.') || ip.startsWith('172.'))
results.localIP.push(ip);
else results.publicIP.push(ip);
}
if (candidate.includes(':')) results.ipv6.push(candidate);
}
};
setTimeout(() => { pc.close(); console.log('Results:', results); }, 2000);
}
Automated Testing with Puppeteer
For CI/CD integration, use Puppeteer to test WebRTC leak behavior programmatically:
const puppeteer = require('puppeteer');
async function testWebRTCLeak() {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--disable-blink-features=WebRTC']
});
const page = await browser.newPage();
await page.evaluateOnNewDocument(() => {
const originalCreateOffer = RTCPeerConnection.prototype.createOffer;
RTCPeerConnection.prototype.createOffer = function(...args) {
console.log('WebRTC createOffer called');
return originalCreateOffer.apply(this, args);
};
});
await page.goto('https://your-target-site.com');
await page.waitForTimeout(3000);
await browser.close();
}
IPv6 Leak Testing
IPv6 addresses can also expose identity. Test specifically for IPv6 leaks:
async function testIPv6Leak() {
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
return new Promise((resolve) => {
pc.onicecandidate = (ice) => {
if (ice.candidate && ice.candidate.candidate.includes(':')) {
resolve({ hasIPv6Leak: true, candidate: ice.candidate.candidate });
pc.close();
}
};
pc.createDataChannel('test');
pc.createOffer().then(o => pc.setLocalDescription(o));
setTimeout(() => { resolve({ hasIPv6Leak: false }); pc.close(); }, 3000);
});
}
Sanitizing Peer Connections
Intercept WebRTC at the connection level to filter sensitive candidates:
const sanitizePeerConnection = () => {
const OriginalRTCPeerConnection = window.RTCPeerConnection;
window.RTCPeerConnection = function(pcConfig, pcConstraints) {
const pc = new OriginalRTCPeerConnection(pcConfig, pcConstraints);
const originalAddIceCandidate = pc.addIceCandidate;
pc.addIceCandidate = function(...args) {
return originalAddIceCandidate.apply(this, args);
};
return pc;
};
};
Network-Level Blocking
For enterprise environments, block STUN traffic at the firewall:
# Block STUN traffic (iptables)
iptables -A INPUT -p udp --dport 3478 -j DROP
iptables -A OUTPUT -p udp --dport 3478 -j DROP
Limitations and Considerations
Blocking WebRTC has trade-offs. Some applications require WebRTC for legitimate features:
- Video conferencing: Google Meet, Zoom, Discord use WebRTC
- Real-time collaboration: Google Docs, Figma
- P2P file sharing: Certain browser-based file transfer tools
If you block WebRTC entirely, these services will fall back to server-relayed connections, potentially increasing latency and bandwidth costs.
Partial Mitigation
Instead of full blocking, restrict WebRTC to proxy traffic:
// Only use proxy for WebRTC (Chrome only)
chrome.proxy.settings.set({
value: {
mode: 'pac_script',
pacScript: {
data: 'function FindProxyForURL(url, host) { return "PROXY proxy:8080"; }'
}
}
}, () => {});
Security Best Practices
- Always test after changes — Use multiple leak test sites
- Check extension permissions — Some malicious extensions can re-enable WebRTC
- Test in incognito mode — Extensions are disabled, revealing true browser behavior
- Verify DNS leaks — Complementary to WebRTC, ensure DNS routes through your VPN
- Keep browser updated — Chrome frequently patches WebRTC behavior
Quick Reference: Method Comparison
| Method | Ease | Reliability | Trade-off |
|---|---|---|---|
| Chrome Flags | Easy | Medium | Breaks all WebRTC |
| Extensions | Easy | Medium | Potential bypass |
| Browser Policies | Medium | High | Requires admin access |
| Firefox Alternative | Easy | High | Different browser |
Conclusion
WebRTC leaks represent a genuine privacy concern for users relying on VPNs or proxies. Chrome provides multiple mechanisms to block these leaks, from simple flags to enterprise policies. Choose the method matching your technical comfort level and use case.
For most users, the Chrome flag or a reputable extension provides sufficient protection. Developers should implement their own detection and mitigation strategies when building privacy-sensitive applications.
Test your configuration regularly—browsers update frequently, and configurations that work today may change with the next release.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one