UDP over SOCKS5: Tunneling QUIC and STUN Traffic to Prevent IP Leaks
Complete guide to UDP over SOCKS5 proxy tunneling. Learn how QUIC and WebRTC STUN traffic can leak your real IP, and how BotBrowser tunnels UDP through SOCKS5 automatically.
Introduction
Most proxy setups focus on TCP traffic. HTTP, HTTPS, and standard web requests all use TCP, and every proxy protocol handles them well. But modern browsers do not use TCP exclusively. Two critical protocols, QUIC (HTTP/3) and WebRTC STUN, rely on UDP. When your proxy only handles TCP, these UDP packets travel directly from your machine to their destination, completely outside the proxy tunnel. The result: your real IP address leaks through UDP traffic while your TCP traffic is safely proxied.
This is not a theoretical risk. Chrome uses QUIC by default for connections to Google services, YouTube, and any site that supports HTTP/3. WebRTC STUN requests use UDP to discover your public IP address for peer-to-peer connections. Both of these protocols actively reveal your real IP if they are not routed through your proxy.
BotBrowser addresses this gap with automatic UDP over SOCKS5 support. When your SOCKS5 proxy supports UDP ASSOCIATE, BotBrowser tunnels QUIC and STUN traffic through it automatically. When it does not, BotBrowser falls back gracefully to TCP-based alternatives without configuration changes.
Privacy Impact
The privacy implications of unprotected UDP traffic are significant. Consider what happens when you configure a standard browser with a SOCKS5 proxy:
QUIC/HTTP/3 traffic leaks your IP to destination servers. When Chrome connects to a site that supports HTTP/3, it attempts a QUIC connection over UDP. If the proxy only handles TCP, this QUIC connection goes direct. The destination server sees your real IP address on the QUIC packets, even though your HTTP/2 fallback traffic goes through the proxy. Google services, YouTube, Cloudflare-hosted sites, and many other major platforms support QUIC.
WebRTC STUN requests expose your public IP. STUN (Session Traversal Utilities for NAT) is a UDP-based protocol that discovers your public IP address. When JavaScript on a page creates an RTCPeerConnection, the browser sends STUN binding requests to STUN servers. These UDP packets go outside the TCP proxy path, and the STUN server returns your real public IP. Any site can collect this through the WebRTC API without user permission.
The inconsistency itself is a signal. If a tracking system observes that your HTTP traffic comes from one IP (the proxy) but your QUIC or STUN traffic reveals a different IP (your real one), the mismatch is a clear indication that a proxy is in use. This inconsistency can be more damaging to privacy than not using a proxy at all.
Technical Background
QUIC (HTTP/3): UDP-Based Web Protocol
QUIC is the transport protocol behind HTTP/3. Unlike HTTP/2, which runs over TCP, QUIC uses UDP to reduce connection latency and improve performance. Chrome uses QUIC by default when the server supports it. Major platforms including Google Search, YouTube, Gmail, Google Cloud, and all Cloudflare-hosted sites support QUIC.
When a browser sends a QUIC packet, it is a UDP datagram. Standard proxy configurations that only handle TCP connections do not intercept this traffic. The QUIC packet goes directly from your machine to the destination server, carrying your real IP in the source address.
STUN (WebRTC): UDP-Based IP Discovery
STUN is a protocol that helps devices behind NAT discover their public IP address. Browsers use STUN as part of WebRTC's ICE (Interactive Connectivity Establishment) process. When JavaScript creates an RTCPeerConnection, the browser sends a STUN binding request (UDP) to a STUN server. The server responds with the public IP address it sees.
This is a deliberate design feature of WebRTC, not a bug. But from a privacy perspective, it means any webpage can discover your real public IP by initiating a STUN request, even when all your HTTP traffic routes through a proxy.
UDP ASSOCIATE: SOCKS5's UDP Forwarding
The SOCKS5 protocol (RFC 1928) defines three command types:
- CONNECT (0x01): Establishes a TCP connection through the proxy. This is what most tools use.
- BIND (0x02): Sets up a TCP listener on the proxy for incoming connections.
- UDP ASSOCIATE (0x03): Establishes a UDP relay through the proxy.
UDP ASSOCIATE is the key to tunneling UDP traffic. Here is how it works:
- The client sends a UDP ASSOCIATE request to the SOCKS5 proxy over TCP
- The proxy allocates a UDP relay endpoint and returns its address
- The client sends UDP packets to this relay endpoint, wrapped in a SOCKS5 UDP header
- The proxy unwraps the header and forwards the UDP packet to the intended destination
- Responses from the destination come back through the proxy relay
The destination server sees UDP packets coming from the proxy's IP, not from your machine. Both QUIC and STUN traffic can use this mechanism.
The Complete Flow
When UDP over SOCKS5 is working correctly, the full flow looks like this:
- Negotiation: BotBrowser establishes a TCP connection to the SOCKS5 proxy and authenticates
- UDP ASSOCIATE request: BotBrowser sends a UDP ASSOCIATE command to request a UDP relay
- Relay allocation: The proxy creates a UDP relay and returns the relay address
- Tunneling: All UDP traffic (QUIC, STUN) is sent through the relay with SOCKS5 encapsulation
- ICE candidates: WebRTC STUN responses return the proxy's IP, so ICE candidates reflect the proxy identity
BotBrowser's Approach
Automatic UDP ASSOCIATE Detection
BotBrowser automatically detects whether your SOCKS5 proxy supports UDP ASSOCIATE. No additional flags or configuration are needed. When you specify a SOCKS5 proxy with --proxy-server, BotBrowser:
- Establishes the TCP control connection to the proxy
- Sends a UDP ASSOCIATE request to probe for UDP support
- If the proxy accepts, BotBrowser creates the UDP relay tunnel
- If the proxy rejects (or does not support UDP ASSOCIATE), BotBrowser falls back to TCP alternatives
This detection happens transparently during proxy initialization.
QUIC Traffic Through the Tunnel
When UDP ASSOCIATE is available, QUIC traffic automatically routes through the SOCKS5 UDP tunnel. Chrome's QUIC implementation treats the tunnel as its network path, so QUIC connections to Google, YouTube, Cloudflare, and other HTTP/3 servers all use the proxy IP.
This means you get the performance benefits of QUIC (lower latency, better connection migration, reduced head-of-line blocking) while maintaining consistent IP identity.
WebRTC STUN Through the Tunnel
STUN binding requests also route through the UDP tunnel. When a page initiates WebRTC and the browser sends STUN requests, those UDP packets go through the SOCKS5 relay. The STUN server sees the proxy's IP address and returns it as the server-reflexive candidate. ICE candidates generated by WebRTC reflect the proxy IP, not your real IP.
This provides the same protection as --bot-webrtc-ice but through a different mechanism: instead of controlling ICE candidate generation at the engine level, the STUN requests themselves travel through the proxy.
Graceful Fallback When UDP Is Not Available
Not all SOCKS5 proxies support UDP ASSOCIATE. Many residential proxy providers and some commercial proxies only handle TCP CONNECT. When BotBrowser detects that UDP ASSOCIATE is not available, it falls back gracefully:
QUIC falls back to HTTP/2 over TCP. Chrome already has this fallback built in. When QUIC is not available (or when UDP is blocked), Chrome uses HTTP/2 over the TCP proxy connection instead. There is no functionality loss. Pages load the same content, just with TCP transport.
STUN can be controlled with --bot-webrtc-ice. If UDP STUN requests cannot route through the proxy, use the --bot-webrtc-ice flag to control ICE candidate generation at the engine level:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-webrtc-ice="google"
This ensures WebRTC ICE candidates show the proxy IP regardless of UDP support.
Configuration and Usage
Basic CLI Setup
The simplest configuration requires only --proxy-server with a SOCKS5 proxy:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080"
If the proxy supports UDP ASSOCIATE, QUIC and STUN traffic will automatically tunnel through it. No additional flags are needed.
Full Privacy Configuration
For comprehensive network protection, combine with DNS and WebRTC controls:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-local-dns \
--bot-webrtc-ice="google"
This configuration covers all network leak paths: TCP traffic through the proxy, UDP traffic through UDP ASSOCIATE (or fallback), DNS through local resolution, and WebRTC through controlled ICE candidates.
Playwright Integration
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy:1080',
'--bot-local-dns',
'--bot-webrtc-ice=google',
],
headless: true,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.youtube.com');
// QUIC traffic to YouTube goes through UDP tunnel
// STUN requests go through UDP tunnel
// All traffic uses proxy IP
await browser.close();
})();
Puppeteer Integration
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy:1080',
'--bot-local-dns',
'--bot-webrtc-ice=google',
],
headless: true,
defaultViewport: null,
});
const page = await browser.newPage();
await page.goto('https://www.youtube.com');
await browser.close();
})();
Per-Context Proxy with Playwright
When managing multiple identities, each browser context can use a different SOCKS5 proxy with independent UDP tunneling:
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
],
headless: true,
});
// Context 1: US proxy with UDP support
const context1 = await browser.newContext({
proxy: {
server: 'socks5://user1:pass1@us-proxy:1080',
},
});
// Context 2: DE proxy with UDP support
const context2 = await browser.newContext({
proxy: {
server: 'socks5://user2:pass2@de-proxy:1080',
},
});
const page1 = await context1.newPage();
const page2 = await context2.newPage();
await page1.goto('https://example.com');
await page2.goto('https://example.com');
await browser.close();
})();
Verifying UDP Tunneling
To confirm that UDP traffic routes through the proxy tunnel, check both QUIC and WebRTC behavior:
const page = await context.newPage();
// 1. Verify HTTP IP matches proxy
await page.goto('https://httpbin.org/ip');
const httpIp = await page.textContent('body');
console.log('HTTP IP:', httpIp);
// 2. Check WebRTC ICE candidates for proxy IP
const candidates = await page.evaluate(() => {
return new Promise((resolve) => {
const ips = [];
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('test');
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]);
} else {
resolve(ips);
}
};
pc.createOffer().then(o => pc.setLocalDescription(o));
});
});
console.log('ICE candidate IPs:', candidates);
// Both should show the proxy IP, not your real IP
Common Scenarios
Scenario 1: SOCKS5 Proxy with UDP Support
This is the ideal configuration. Your SOCKS5 proxy supports UDP ASSOCIATE, and BotBrowser tunnels all traffic automatically.
| Traffic Type | Path | Result |
|---|---|---|
| HTTP/HTTPS (TCP) | Browser -> Proxy -> Destination | Proxy IP visible |
| QUIC/HTTP/3 (UDP) | Browser -> Proxy UDP Relay -> Destination | Proxy IP visible |
| STUN (UDP) | Browser -> Proxy UDP Relay -> STUN Server | Proxy IP returned |
| DNS | Controlled by --bot-local-dns | No leak |
Configuration:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-local-dns
Scenario 2: SOCKS5 Proxy Without UDP Support
Many SOCKS5 proxies, especially residential proxies, only support TCP CONNECT. BotBrowser detects this and falls back automatically.
| Traffic Type | Path | Result |
|---|---|---|
| HTTP/HTTPS (TCP) | Browser -> Proxy -> Destination | Proxy IP visible |
| QUIC/HTTP/3 | Falls back to HTTP/2 over TCP | Proxy IP visible |
| STUN (UDP) | Controlled by --bot-webrtc-ice | Proxy IP in candidates |
| DNS | Controlled by --bot-local-dns | No leak |
Configuration:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-webrtc-ice="google" \
--bot-local-dns
The --bot-webrtc-ice flag ensures WebRTC protection even without UDP tunneling.
Scenario 3: HTTP/HTTPS Proxy (No UDP Support)
HTTP and HTTPS proxies use the CONNECT method for TCP tunneling. They do not support UDP at all. BotBrowser handles this the same way as a SOCKS5 proxy without UDP support.
| Traffic Type | Path | Result |
|---|---|---|
| HTTP/HTTPS (TCP) | Browser -> Proxy (CONNECT) -> Destination | Proxy IP visible |
| QUIC/HTTP/3 | Falls back to HTTP/2 over TCP | Proxy IP visible |
| STUN (UDP) | Controlled by --bot-webrtc-ice | Proxy IP in candidates |
| DNS | Controlled by --bot-local-dns | No leak |
Configuration:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="http://user:pass@proxy:8080" \
--bot-webrtc-ice="google" \
--bot-local-dns
Best Practices
-
Use SOCKS5 proxies with UDP support when possible. This provides the most complete protection with the least configuration. QUIC and STUN traffic tunnel automatically.
-
Always add --bot-webrtc-ice as a safety net. Even with UDP tunneling, the
--bot-webrtc-iceflag provides an additional layer of WebRTC protection in case the UDP tunnel drops. -
Combine with --bot-local-dns for complete coverage. UDP tunneling, WebRTC control, and DNS leak prevention together close all major network leak paths.
-
Test your proxy's UDP support. Not all proxies advertise their UDP ASSOCIATE capability clearly. Use the verification steps above to confirm that UDP traffic actually routes through the tunnel.
-
Do not disable QUIC manually. Some guides suggest disabling QUIC with
--disable-quic. This is unnecessary with BotBrowser. When UDP ASSOCIATE is available, QUIC works through the tunnel. When it is not, QUIC falls back to HTTP/2 automatically. Disabling QUIC entirely may create a detectable fingerprint. -
Check proxy provider documentation. Ask your proxy provider whether they support SOCKS5 UDP ASSOCIATE. Providers that support it include most datacenter SOCKS5 proxies and some premium residential providers.
Frequently Asked Questions
Does UDP over SOCKS5 require any special BotBrowser flags?
No. BotBrowser detects UDP ASSOCIATE support automatically when you use --proxy-server with a SOCKS5 proxy. No additional flags are needed for UDP tunneling itself.
What happens if my proxy does not support UDP ASSOCIATE?
BotBrowser falls back gracefully. QUIC traffic downgrades to HTTP/2 over TCP (still through the proxy). For WebRTC protection, add --bot-webrtc-ice to control ICE candidates at the engine level.
Does this work with SOCKS5H proxies?
Yes. The socks5h:// scheme tells BotBrowser to resolve DNS through the proxy. UDP ASSOCIATE works the same way with both socks5:// and socks5h:// schemes.
Can I use UDP over SOCKS5 with per-context proxies in Playwright? Yes. Each browser context can have its own SOCKS5 proxy, and BotBrowser will probe UDP ASSOCIATE support independently for each proxy connection.
Does UDP tunneling affect performance? The overhead is minimal. The SOCKS5 UDP encapsulation adds a small header to each UDP packet. For QUIC traffic, you still get the latency benefits of HTTP/3 compared to HTTP/2 fallback. The relay adds one network hop, similar to TCP proxying.
Is UDP ASSOCIATE the same as full UDP proxy support? UDP ASSOCIATE is the specific SOCKS5 mechanism defined in RFC 1928 for relaying UDP traffic. It is the standard way to tunnel UDP through SOCKS5. Some proxy providers may describe their UDP support differently, but at the protocol level, it is UDP ASSOCIATE.
Do HTTP/HTTPS proxies support UDP? No. HTTP and HTTPS proxies use the HTTP CONNECT method, which only supports TCP. If you need UDP tunneling, you must use a SOCKS5 proxy.
How can I tell if my QUIC traffic is going through the tunnel?
Navigate to chrome://net-internals/#quic in BotBrowser. If QUIC sessions are active and your proxy supports UDP, the traffic is tunneling correctly. You can also check chrome://flags/#enable-quic to confirm QUIC is enabled.
Summary
UDP traffic is a significant and often overlooked privacy gap in proxy-based setups. QUIC and WebRTC STUN both use UDP, and both can expose your real IP when your proxy only handles TCP. BotBrowser closes this gap by automatically detecting SOCKS5 UDP ASSOCIATE support and tunneling all UDP traffic through the proxy. When UDP support is not available, BotBrowser falls back to TCP alternatives without any manual configuration.
For complete network privacy, combine UDP over SOCKS5 with Proxy Configuration, WebRTC Leak Prevention, and DNS Leak Prevention.