WebRTC is the browser standard for real-time audio, video and data between two endpoints. It has two halves: a W3C JavaScript API (RTCPeerConnection and friends) and an IETF protocol suite, indexed by RFC 8825, that finds a network path with ICE, STUN and TURN and then encrypts everything with DTLS and SRTP. Encryption is mandatory, but the path discovery that makes calls work also reveals IP addresses, and that is where most of the privacy questions come from.
For a defender the short version is this: the media is well protected, signalling is your problem by design, IP address handling is a policy you should set deliberately, and a TURN relay can reach anything its host can reach unless you tell it otherwise.
Key takeaways
- WebRTC is defined by the W3C Recommendation "WebRTC: Real-Time Communication in Browsers" (first a Recommendation in January 2021, current version 13 March 2025) and the IETF RFC 8825 to RFC 8835 cluster from January 2021.
- Signalling is deliberately out of scope. Your application carries session descriptions over its own channel, usually WebSocket or HTTPS.
- ICE (RFC 8445) gathers candidates, checks them with STUN (RFC 8489) and falls back to a TURN relay (RFC 8656). STUN and TURN default to port 3478 over UDP and TCP and 5349 over TLS or DTLS.
- RFC 8827 makes encryption non-negotiable: SRTP keyed by DTLS-SRTP (RFC 5764) for media, DTLS for data channels, no NULL ciphers, no keys in signalling.
- The privacy cost is IP address exposure. RFC 8828 defines four address handling modes, and Chrome and Edge expose them as enterprise policies.
- coturn allows anonymous access when no authentication option is set and relays to any peer address you do not deny. Turn on credentials and deny internal ranges.
- WHIP (RFC 9725, March 2025) standardises HTTP based WebRTC ingest; WHEP, for playback, is still an Internet-Draft.
What WebRTC is for: the layer and the standards
WebRTC lets two endpoints, at least one usually a browser, exchange real-time media and arbitrary data with low latency, through NATs and firewalls, without a plug-in, and without the web page ever touching the encryption keys.
It is a profile rather than a single protocol. RFC 8825, "Overview: Real-Time Protocols for Browser-Based Applications" (January 2021), calls itself an applicability statement that "does not itself specify any protocol"; it lists the specifications an implementation must follow. The pieces sit at different layers:
| Piece | Standard | Layer | Runs over |
|---|---|---|---|
| RTCPeerConnection, RTCDataChannel | W3C WebRTC Recommendation | Browser API | JavaScript |
| Session negotiation (JSEP) | RFC 9429, April 2024 (obsoletes RFC 8829) | Signalling model | Whatever channel the app builds |
| Path discovery | ICE, RFC 8445, July 2018 | Connectivity | UDP, and TCP via RFC 6544 |
| Address discovery and checks | STUN, RFC 8489, February 2020 | Connectivity | UDP, TCP, TLS, DTLS |
| Relay | TURN, RFC 8656, February 2020 | Connectivity | UDP, TCP, TLS, DTLS |
| Key exchange | DTLS-SRTP, RFC 5764, May 2010 | Security | UDP on the ICE path |
| Media protection | SRTP, RFC 3711, March 2004 | Transport security | UDP |
| Data channels | SCTP over DTLS, RFC 8831 and RFC 8832 | Transport | DTLS over UDP |
| Consent freshness | RFC 7675, October 2015 | Security | STUN on the ICE path |
The browser profile was published together in January 2021: RFC 8825 (overview), RFC 8826 (security considerations), RFC 8827 (security architecture), RFC 8828 (IP address handling), RFC 8831 and RFC 8832 (data channels), RFC 8834 (RTP usage) and RFC 8835 (transports), among others. The W3C API became a Recommendation the same month and was republished with integrated amendments on 13 March 2025.
Two things WebRTC does not standardise matter for security: signalling (how peers find each other and swap descriptions) and identity (who is really on the other end). RFC 8827 defines an optional identity provider mechanism, but most applications rely on their own login and signalling server, which puts the operator in a position of trust the protocol cannot remove.
How a WebRTC call is set up
A session goes through signalling, candidate gathering, connectivity checks, the DTLS handshake, and then media or data with ongoing consent checks.
Browser A Signalling server STUN/TURN Browser B
| | | |
|-- SDP offer ---------->| (codecs, ice-ufrag, | |
| | ice-pwd, fingerprint) |
| |------- offer --------------------------> |
| |<------ answer ---------------------------- |
|<-- answer -------------| | |
|== STUN Binding (learn server reflexive addr) ==>| |
|== TURN Allocate, 401 challenge, retry =========>| |
|<========================= relayed address =====| |
|-- candidates trickled over signalling ----------------------------> |
|<---------------------------------------------------- candidates ---|
|== ICE checks: STUN Binding with USERNAME and HMAC =================>|
|<===================================== STUN Binding success ========|
| (controlling agent nominates the best working pair) |
|== DTLS ClientHello + use_srtp =====================================>|
|<= ServerHello + use_srtp, Certificate ... =========================|
| (each side checks the peer certificate against the SDP fingerprint)
|<================= SRTP media / SCTP-over-DTLS data ===============>|
|== STUN consent checks every few seconds ===========================>|
Signalling and SDP
The W3C specification says peers exchange control messages "over a signaling channel which is provided by unspecified means, but generally by a script in the page via the server, e.g. using WebSocket or XMLHttpRequest." JSEP (RFC 9429) defines how the browser produces and consumes SDP offers and answers. The SDP carries the values that tie the session together:
a=ice-ufraganda=ice-pwd: short-term credentials that authenticate ICE connectivity checks.a=fingerprint: a hash of the DTLS certificate the endpoint will present, which binds the encrypted media to the signalling exchange.a=setup: which side is the DTLS client and which the server.
Because the fingerprint arrives over signalling, whoever controls signalling controls which certificate each side accepts. That returns in the security section.
ICE candidates and STUN
ICE (RFC 8445, which obsoleted RFC 5245 and has been updated by RFC 8863) finds a working path. Each agent gathers candidates:
| Candidate type | Source | Recommended type preference (RFC 8445) |
|---|---|---|
| Host | Address on a local interface (Ethernet, Wi-Fi, VPN) | 126 |
| Peer reflexive | Learned during connectivity checks | 110 |
| Server reflexive | Public address a NAT assigned, reported by STUN | 100 |
| Relayed | Address allocated on a TURN server | 0 |
Priority is two to the 24th times the type preference, plus two to the 8th times a local preference, plus 256 minus the component ID. With the recommended values direct paths are always tried before relays, which is good for latency and is why real addresses are exposed by default. The agents pair candidates and send STUN Binding requests between them, authenticated with the ufrag and password. The controlling agent nominates the pair to use; RFC 8445 removed the "aggressive nomination" mode of RFC 5245. Checks are paced by a timer, Ta, with a default of 50 ms.
Every STUN message starts with a 20-byte header:
| Bits | Field | Meaning |
|---|---|---|
| 2 | Leading zeros | Always 00, which helps separate STUN from other protocols on the same port |
| 14 | Message type | 12-bit method (Binding is the only method in RFC 8489) interleaved with a 2-bit class: request, indication, success, error |
| 16 | Message length | Length of the attributes |
| 32 | Magic cookie | Fixed value 0x2112A442 |
| 96 | Transaction ID | Random value pairing requests with responses |
Attributes follow in type, length, value form. The security-relevant ones are XOR-MAPPED-ADDRESS (the address the server saw, obfuscated so NATs do not rewrite it), USERNAME, MESSAGE-INTEGRITY (HMAC-SHA1), MESSAGE-INTEGRITY-SHA256 (new in RFC 8489) and FINGERPRINT. A Binding request encodes as 0x0001 and a success response as 0x0101.
TURN relays
When no direct pair works, ICE uses a relayed candidate. TURN (RFC 8656) extends STUN with relay methods:
| TURN concept | What it is | Lifetime per RFC 8656 |
|---|---|---|
| Allocation | Relayed address on the server, owned by one client | 10 minutes unless refreshed; servers should cap requested lifetimes at 3600 seconds |
| Permission | Lets traffic from one peer IP reach the client | 300 seconds, must be refreshed |
| Channel binding | Compact 4-byte header alternative to Send and Data indications | 10 minutes; channel numbers 0x4000 to 0x4FFF |
Allocate requests use STUN's long-term credential mechanism, which RFC 8656 makes mandatory to implement: the first request draws a 401 with a realm and nonce, and the retry carries a MESSAGE-INTEGRITY computed from the credentials. RFC 8835 requires browsers to support TURN over TCP and over TLS so calls survive networks that block all UDP.
DTLS-SRTP and SRTP
Once ICE has a pair, the endpoints run DTLS directly over it. RFC 5764 adds a use_srtp extension to agree an SRTP protection profile and exports keys from the DTLS session; in the RFC's words, "DTLS keying happens on the media path, independent of any out-of-band signalling channel." Each side checks the peer certificate, usually self-signed, against the SDP fingerprint. That check is the only peer authentication in a typical call.
STUN, DTLS and SRTP share one UDP port, so receivers demultiplex by the first byte (RFC 5764 section 5.1.2, later updated by RFC 7983 and RFC 9443):
| First byte | Packet type |
|---|---|
| 0 or 1 | STUN |
| 20 to 63 | DTLS |
| 128 to 191 | RTP or RTCP (SRTP, SRTCP) |
SRTP (RFC 3711) encrypts the RTP payload but not the header:
| SRTP packet part | Encrypted | Authenticated |
|---|---|---|
| RTP header and extensions | No | Yes |
| RTP payload | Yes | Yes |
| Master Key Identifier (optional; RFC 8827 forbids it in WebRTC) | No | No |
| Authentication tag | Not applicable | It is the authenticator |
An on-path observer therefore still sees payload type, sequence numbers, timestamps and the source identifier, plus packet sizes and timing, though not the media.
Data channels, consent and teardown
RTCDataChannel runs SCTP over DTLS over the ICE path (RFC 8831, with the encapsulation in RFC 8261). RFC 8831 chose this stack because it supports arbitrarily large messages, shares the DTLS connection with the media, and "provides privacy for the SCTP control information." Each channel can be ordered or unordered and reliable or partially reliable. RFC 8832 adds DCEP: one side sends DATA_CHANNEL_OPEN and the other replies DATA_CHANNEL_ACK; the DTLS client uses even stream identifiers and the DTLS server odd ones.
During the call each side keeps sending STUN Binding requests on the selected pair. Under RFC 7675, consent expires after 30 seconds without a valid response and the sender must stop; implementations should check every 5 seconds by default. A session ends when either side closes the connection, consent expires, or an ICE restart moves it to a new path.
Versions and history
| Date | Specification | What changed |
|---|---|---|
| March 2004 | RFC 3711, SRTP | Encryption and authentication for RTP |
| October 2008 | RFC 5389, STUN | Magic cookie and modern format (obsoleted by RFC 8489) |
| May 2010 | RFC 5764, DTLS-SRTP | Keys negotiated on the media path, not in signalling |
| October 2015 | RFC 7675 | STUN based consent freshness |
| July 2018 | RFC 8445, ICE | Obsoletes RFC 5245; removes aggressive nomination, changes Ta and RTO, moves SIP and SDP specifics out |
| February 2020 | RFC 8489, STUN | DTLS transport, SHA-256 integrity, password algorithm negotiation against bid-down, anonymous usernames, no shared nonces |
| February 2020 | RFC 8656, TURN | Obsoletes RFC 5766 and RFC 6156; adds IPv6, DTLS, ICMP relay, server discovery, documents tunnel amplification |
| January 2021 | RFC 8825 to RFC 8835 and W3C WebRTC 1.0 | The browser profile and API |
| April 2024 | RFC 9429, JSEP | Obsoletes RFC 8829 |
| 13 March 2025 | W3C WebRTC Recommendation | Republished with integrated amendments |
| March 2025 | RFC 9725, WHIP | HTTP based ingest; updates RFC 8840 and RFC 8842 |
Older choices still show up in deployments. RFC 8827 requires DTLS 1.2 but notes earlier drafts required DTLS 1.0 and some implementations then supported only that. Chrome's enterprise policy documentation describes DTLS 1.0 as disabled by default for WebRTC, with an override policy that existed from Chrome 87 to 120 and was removed in 121. It also lists a WebRtcPostQuantumKeyAgreement policy, from Chrome 140, controlling whether post-quantum key agreement is offered in the DTLS handshake, described as temporary. WHEP was at draft-ietf-wish-whep-05, submitted to the IESG, when we checked the datatracker.
Security properties: what WebRTC guarantees
RFC 8826 analyses the threats and RFC 8827 answers them. The starting assumption is that the web page itself may be malicious, so the browser enforces protections the page cannot turn off. RFC 8827 requires:
- Media confidentiality and integrity. All media over SRTP and SRTCP, never plain RTP, no NULL ciphers, DTLS-SRTP offered for every media channel, and SDP security descriptions (keys in signalling) neither offered nor accepted. SRTP_AES128_CM_HMAC_SHA1_80 must be supported.
- Data confidentiality and integrity. All data channels over DTLS.
- Baseline cryptography. DTLS 1.2 with TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 and P-256 is mandatory to implement; forward secrecy must be preferred and AEAD should be; DTLS renegotiation and TLS False Start are prohibited.
- Keys out of reach of the page. JavaScript must not be able to obtain the SRTP keying material.
- Unlinkability. A new key pair per call by default, and different key pairs per origin, so a certificate cannot become a super-cookie.
- Consent to receive. ICE must confirm reachability before any non-ICE packet is sent, the STUN transaction ID stays hidden from JavaScript, and the page cannot set the local ufrag and password. This stops a page from aiming traffic at a host that never agreed to receive it.
The W3C spec adds that browsers always use congestion control, so WebRTC "cannot be used to flood the network."
What WebRTC does not guarantee:
- Peer authentication beyond the fingerprint. RFC 8826 says it is "extremely difficult to prevent a trusted but malicious calling service from actively attacking a user's calls."
- Metadata privacy. "The fact that communication is taking place cannot be hidden from adversaries that can observe the network," per the W3C spec.
- IP privacy from the peer by default. RFC 8827 notes the peer learns your IP address, "which leaks large amounts of location information."
- Protection from the other participant. RFC 8826 does not try to stop a peer recording a call.
Weakness classes, as concepts
These are classes the standards themselves describe, at the level of what goes wrong and why the design allows it.
Local IP address exposure and fingerprinting
ICE works by advertising addresses, and host candidates can include private and VPN interface addresses. RFC 8445 warns that "server-reflexive addresses gathered through the local interface of VPN users, may be sensitive information." The W3C spec adds that the address set "can leak location and means of connection" and can create "persistent cross-origin state", while codec capability lists widen the fingerprinting surface.
The design allows it because the most direct path gives the best quality. RFC 8828 resolves the trade-off with four modes:
| RFC 8828 mode | Behaviour | Exposure |
|---|---|---|
| Mode 1, all addresses | Use every interface | Most disclosed; must not be used without user consent |
| Mode 2, default route plus local addresses | Follow the routing table; expose private addresses on that interface | Recommended default without consent |
| Mode 3, default route only | No private addresses; only STUN and TURN discovered ones | Less exposure; may force relaying |
| Mode 4, force proxy | As Mode 3, and send media through the configured proxy, falling back to TCP | Least exposure, worst quality |
Chrome and Edge policy documentation also describes concealing local IP addresses in ICE candidates behind mDNS hostnames when that feature is enabled, unless an administrator allowlists an origin. The so-called "WebRTC leak" is this class: a page can learn an address the user assumed was hidden, such as the real public address of a machine whose web traffic goes through a proxy, if the browser gathers candidates outside the proxied route. Modes 3 and 4 close that gap. Our post on what a DNS leak is and how to stop it covers the matching problem for name lookups.
The peer learns your address
Even with private addresses hidden, the remote party learns your server reflexive address in a direct call. RFC 8827 requires two controls: a way to delay ICE until the user answers, so an unanswered caller cannot learn your address or whether you are online, and a way to use only TURN candidates. The W3C API exposes the second as iceTransportPolicy: "relay", whose note describes letting an app "prevent an unknown caller from learning the callee's IP addresses until the callee has consented." Neither hides your address from the web server, which learns it from any HTTP request.
Open or over-reaching TURN relays
RFC 8656 requires authentication and says most attacks on TURN "are mitigated by the server requiring requests be authenticated." Yet coturn's documentation says its no-authentication mode is the "default option when no authentication-related options are set." An open relay hides its users' real addresses from targets and can be chained, which RFC 8656 section 21.3.2 notes makes it attractive for laundering traffic.
The second problem is reach. RFC 8656 says TURN "should not weaken the protections afforded by firewalls" and that servers may restrict the peer addresses they relay to. A TURN server inside a cloud network or behind a NAT with no restrictions lets an authenticated client send packets to internal services, loopback or link-local addresses it could never reach directly: a server-side request forgery class problem at the transport layer. coturn describes its peer address lists as being for when "you do not want users of the turn server to be able to access machines reachable by the turn server, but would otherwise be unreachable from the internet." Our post on ASVS V17.1.1 and blocking reserved IP ranges on TURN servers covers the requirement.
RFC 8656 lists more classes: resource exhaustion by legitimate users (mitigated by per-user bandwidth limits and allocation quotas); tunnel amplification between a TURN server and an IPv4 to IPv6 tunnel (limited by MTU, about four to one in the RFC's example; servers must not accept Teredo or 6to4 addresses); and tampering with other users' allocations or faking permissions (prevented because those requests must be authenticated with the allocation's own credentials).
Unauthenticated or untrusted signalling
Signalling security is entirely the application's. If it runs over plain HTTP or WebSocket, or lacks authentication and authorisation, anyone who can tamper with it can swap the SDP fingerprints and relay the call through themselves; RFC 8826 notes this "applies equally to a network attacker if communications to the calling service are not secured." The defences are ordinary web security: HTTPS and secure WebSocket, authenticated users, room authorisation, and message validation. See our WebSocket security guide.
The deeper issue is that the service operator is trusted. RFC 8826 separates retrospective compromise, which DTLS-SRTP's forward secrecy and page-proof keys defend against, from a during-call attack by the operator, which needs out-of-band fingerprint checks, short authentication strings or third-party identity. A media server that terminates DTLS for each participant can see the media unless the application adds end-to-end encryption on top.
Permission prompts and screen sharing
Browsers prompt for camera, microphone and screen capture, but the W3C spec states WebRTC itself "provides no user prompts or chrome indicators for communication." Once a page has media it can share it as it chooses, and data channels can run "without any user explicit consent." Permission is to the origin, not to a specific call. RFC 8827 requires a visible indicator while camera or microphone are in use and forbids permanent screen or application sharing permissions; RFC 8826 explains why a shared browser window can reveal content from other origins.
WHIP endpoint abuse
RFC 9725 describes a "thin new attack surface": a holder of valid credentials can flood the endpoint with POSTs that each tie up ICE and DTLS resources until timeout, and guessable session URLs let an attacker DELETE other people's streams, an insecure direct object reference. It recommends rate limiting and session URLs from a cryptographically secure random generator, and requires HTTPS "in order to preserve the WebRTC security model."
Secure configuration and how to check it
The commands below come from coturn's official documentation, the Linux ss manual page and Microsoft Learn. Only run them against systems you own or are authorised to test.
TURN servers (coturn)
coturn reads turnserver.conf; its README lists /etc/turnserver.conf and /usr/local/etc/turnserver.conf among the default locations. The settings that matter, as named in that README:
- Authentication.
lt-cred-mechenables long-term credentials, which the README says "you need for WebRTC usage." Set arealm. For browser apps preferuse-auth-secretwithstatic-auth-secret, where your backend issues short-lived credentials of the form timestamp:username with an HMAC-derived password. Static passwords in front-end JavaScript are visible to every visitor. - Peer restrictions.
denied-peer-ipandallowed-peer-iptake addresses or ranges; an address matching both is allowed. Loopback peers are refused unlessallow-loopback-peersis set, which coturn says to use "only for testing in a development environment."no-multicast-peersrefuses broadcast and multicast peers. - Never
server-relay. The README calls it "NON-STANDARD AND DANGEROUS"; it removes the permission check on relay endpoints. - Quotas.
user-quota,total-quotaandmax-bpsimplement RFC 8656's insider-attack mitigations. - TLS.
no-tlsv1_2makes TLS 1.3 and DTLS 1.2 the minimum;tlsv1andtlsv1_1lower it and do not belong in production. - Management. The CLI is off unless
cliis set; if used, keepcli-ipon 127.0.0.1 with an encryptedcli-password. Web admin is disabled by default.secure-stunrequires authentication for STUN Binding requests, which are anonymous by default. - Logging.
log-fileorsyslog, so you keep client source addresses for tracing relayed abuse, as RFC 8656 suggests.
A hardened excerpt with example ranges:
# turnserver.conf (excerpt)
realm=turn.example.com
use-auth-secret
static-auth-secret=REPLACE_WITH_LONG_RANDOM_SECRET
# Refuse to relay to internal and special-purpose space
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=::1
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
no-multicast-peers
user-quota=12
total-quota=1200
max-bps=3000000
no-tlsv1_2
syslog
Check what is configured and listening:
# Hardening options present in the deployed config
grep -E '^(lt-cred-mech|use-auth-secret|realm|denied-peer-ip|allowed-peer-ip|no-multicast-peers|allow-loopback-peers|server-relay|user-quota|total-quota|max-bps|no-tlsv1_2|tlsv1|tlsv1_1|secure-stun|cli|syslog|log-file)' /etc/turnserver.conf
# Listening UDP and TCP sockets with owning process (ss: -u UDP, -t TCP, -l listening, -n numeric, -p process)
ss -ulnp
ss -tlnp
Expect 3478 on UDP and TCP, 5349 for TLS (and DTLS only if you enabled it, since coturn does not start DTLS listeners by default), and nothing on the CLI port 5766 except loopback.
coturn's README.turnutils documents test clients. turnutils_stunclient sends a Binding request and prints the reply. turnutils_uclient, "supplied for the test purposes only", opens an allocation toward a peer address; pointed at your own server with a peer inside a denied range, the relay attempt should fail, which proves the deny list works:
turnutils_stunclient -p 3478 turn.example.com
turnutils_uclient -u testuser -w testpassword -e 10.0.0.5 turn.example.com
Browsers (enterprise policy)
| Policy | Values | Effect |
|---|---|---|
| Chrome WebRtcIPHandling (91 and later) | default, default_public_and_private_interfaces, default_public_interface_only, disable_non_proxied_udp | Restricts interfaces and addresses; Google points to RFC 8828 section 5.2 for each value |
| Chrome WebRtcIPHandlingUrl (133 and later) | URL pattern and handling pairs | Per-origin version |
| Edge WebRtcLocalhostIpHandling (77 and later) | AllowAllInterfaces, AllowPublicAndPrivateInterfaces, AllowPublicInterfaceOnly, DisableNonProxiedUdp | Microsoft says the last two do not expose the local IP |
| Chrome and Edge WebRtcLocalIpsAllowedUrls | Origins | Origins that see real local IPs instead of mDNS names |
| Chrome and Edge WebRtcUdpPortRange | A range such as 10000-11999 | Limits local UDP ports, which keeps firewall rules narrow |
Read against RFC 8828, the four values map to Modes 1 to 4 in order. For managed fleets behind a proxy, the public-interface-only value (Mode 3) is the usual compromise; the proxy-only value gives the strongest guarantee at a real cost in call quality. Keep WebRtcLocalIpsAllowedUrls empty unless an internal application needs host candidates. Microsoft documents the Edge registry location as SOFTWARE\Policies\Microsoft\Edge; read it with the reg query syntax from Microsoft Learn:
reg query HKLM\SOFTWARE\Policies\Microsoft\Edge /v WebRtcLocalhostIpHandling
reg query HKLM\SOFTWARE\Policies\Microsoft\Edge /v WebRtcUdpPortRange
Your application
- Use
iceTransportPolicy: "relay"until both parties consent to sharing addresses, and delay ICE until the callee answers. - Mint short-lived TURN credentials server-side after login.
- Serve the app and signalling over HTTPS and secure WebSocket only, and authorise room membership on the server.
- Offer fingerprint comparison or a short authentication string if your threat model includes the operator.
- For WHIP, require bearer tokens, rate limit POST, PATCH and DELETE, and use unguessable session URLs.
When to use WebRTC and when to use something else
| Option | Best for | Security properties | Operational cost |
|---|---|---|---|
| WebRTC, peer to peer | Browser calls, low-latency peer data | Mandatory DTLS-SRTP and DTLS; ICE consent; IP exposure unless relay-only | STUN, TURN and your own signalling |
| WebRTC through a media server | Group calls, recording, moderation | Encrypted per leg; server sees media unless the app adds end-to-end encryption | Media servers plus TURN |
| SIP with RTP and SRTP | Telephony, PBX and carrier interconnect | SRTP and SIP over TLS optional; keying varies by deployment | Mature tooling; encryption policy is yours |
| WebSocket media relay | Simple server-mediated streams | TLS to the server; server sees everything; TCP head-of-line blocking | Easy to build, costly bandwidth |
| WHIP ingest (RFC 9725) | Publishing a live stream with sub-second latency | WebRTC media security plus HTTPS and bearer tokens | HTTP endpoint plus media servers |
| WHEP egress (draft) | WebRTC playback | Same model as WHIP | Still a draft |
Choose WebRTC when latency matters and one end is a browser, SIP when interconnecting with telephony, and WHIP for ingest where your platform supports it. Our TCP vs UDP post explains why the UDP underneath still exposes addresses and timing.
Where Safeguard fits
Safeguard does not inspect, relay or filter WebRTC traffic, and it does not configure browsers or TURN servers. The connection is the software you ship: native WebRTC stacks in mobile and desktop apps, SRTP and user-space SCTP libraries, the DTLS library underneath, media servers and coturn container images. Safeguard's software composition analysis and SBOM generation (SPDX and CycloneDX), both generally available, inventory those components and their transitive dependencies; vulnerability management with EPSS and KEV enrichment and reachability analysis, also generally available, rank what your code actually calls; and first-party DAST, generally available for verified targets, can test your signalling and WHIP HTTP and WebSocket endpoints. Our post on using SBOMs to find affected products fast shows the workflow when an advisory lands.
Common mistakes
- coturn without authentication. With no authentication option set, access is anonymous.
- No peer restrictions on a TURN server inside a private network. Authenticated users can relay into internal ranges.
- Static TURN credentials in front-end code. Anyone can read and reuse them.
- Treating signalling as someone else's problem. The fingerprints that authenticate the media travel over it.
- Believing encrypted means private. SRTP hides content, not who talks to whom, when, or how much.
- Assuming a proxy or VPN hides your address from WebRTC. That depends on the browser's IP handling policy.
- Enabling
allow-loopback-peersorserver-relayin production. coturn's documentation warns against both. - Guessable WHIP session URLs. RFC 9725 warns they let others end your streams.
FAQ
What port does WebRTC use?
There is no single port. Media and data use whatever UDP ports ICE negotiates; Chrome's documentation says WebRTC can use any available local UDP port unless WebRtcUdpPortRange is set. STUN and TURN servers default to 3478 for UDP and TCP and 5349 for TLS and DTLS. Signalling uses whatever your app chooses, usually HTTPS on 443.
Is WebRTC encrypted?
Always. RFC 8827 requires SRTP keyed by DTLS-SRTP for media and DTLS for data channels, and forbids unencrypted RTP. Metadata such as IP addresses, ports, RTP headers, sizes and timing is not encrypted.
Is WebRTC end-to-end encrypted?
In a direct call between two browsers, the keys exist only in those browsers, provided signalling delivered the right fingerprints. Through a media server that terminates DTLS, each leg is encrypted to the server, which can see the media.
Does WebRTC leak my IP address?
It can. ICE shares candidate addresses with the page and the peer. Browsers can hide local addresses behind mDNS names, but the peer still learns your public address in a direct call. Relay-only ICE in the app, or a Mode 3 or Mode 4 browser policy, prevents that.
What is the difference between STUN and TURN?
STUN (RFC 8489) tells a client its public address and carries ICE connectivity checks; media does not flow through it. TURN (RFC 8656) allocates a relay and forwards the media when no direct path works, so it needs authentication and bandwidth.
Do I need a TURN server for WebRTC?
For production, yes. Some users sit behind NATs or firewalls where no direct path works, and relay-only privacy settings depend on TURN.
WebRTC vs WebSocket: which should I use?
WebSocket is a TCP message channel to a server and a common choice for WebRTC signalling. WebRTC carries real-time media and peer data over UDP with congestion control. Use WebSocket for control and server push, WebRTC for audio, video and low-latency peer data.
What is WHIP?
The WebRTC-HTTP Ingestion Protocol (RFC 9725, March 2025) lets an encoder publish a stream by POSTing an SDP offer to an HTTP endpoint, receiving an SDP answer and a session URL, and ending with an HTTP DELETE. It carries a single MediaStream per session and requires HTTPS and bearer token support.
Fix it without waiting for upstream
WebRTC vulnerabilities rarely live in your own code. They usually sit in a library or daemon you depend on: a media stack compiled into your app, an SRTP or SCTP library, the DTLS implementation underneath it, a media server, or the TURN server image you deploy.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
These demos show dependency, SBOM and remediation workflows, not network monitoring. You can download Safeguard and follow the CLI docs to try them on your own projects.
This demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. Pointed at the container image for your TURN server or media server, the same scan lists the DTLS, SRTP and other libraries inside it with their versions and any known vulnerabilities.
Click through it at your own pace, or open it full screen.
This demo is a real CLI session: install, open the interactive terminal, ask it to fix the lodash CVE in a repository, and watch it read the finding and advisory, ask before each command, move lodash to 4.17.21, run npm install and npm test with approval, and print a summary without pushing anything. The same approve each step flow applies when the package to bump is a WebRTC client library or signalling server dependency in your manifest.
Click through it at your own pace, or open it full screen.
This demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Once connected, you can ask in plain language which of your projects ship a particular media or DTLS library version, and get the answer from your own scan data rather than from memory.
Click through it at your own pace, or open it full screen.
Quick check
Your calling app encrypts every call with DTLS-SRTP. Can a compromised signalling server still listen in?
Yes, if it is compromised during the call. The DTLS certificate fingerprints that authenticate each side travel over signalling, so whoever controls signalling can substitute their own and bridge the call. RFC 8826 says protecting against this needs out-of-band fingerprint checks or a third-party identity system. A server compromised only after the call cannot decrypt it, because the page never sees the keys.
Your TURN server requires credentials. Is that enough?
No. Authentication stops strangers, but an authenticated user can still ask the relay to reach any address the server can reach. Deny private, loopback, link-local and other special-purpose ranges with peer address restrictions, set per-user quotas and bandwidth limits, and keep logs of client source addresses, as RFC 8656 and coturn's documentation describe.
Sources
- W3C Recommendation: WebRTC, Real-Time Communication in Browsers (13 March 2025)
- RFC 8825: Overview, Real-Time Protocols for Browser-Based Applications
- RFC 8826: Security Considerations for WebRTC
- RFC 8827: WebRTC Security Architecture
- RFC 8828: WebRTC IP Address Handling Requirements
- RFC 8445: Interactive Connectivity Establishment (ICE)
- RFC 8489: Session Traversal Utilities for NAT (STUN)
- RFC 8656: Traversal Using Relays around NAT (TURN)
- RFC 5764: DTLS Extension to Establish Keys for SRTP
- RFC 3711: The Secure Real-time Transport Protocol (SRTP)
- RFC 7675: STUN Usage for Consent Freshness
- RFC 8831: WebRTC Data Channels
- RFC 8832: WebRTC Data Channel Establishment Protocol
- RFC 8834: Media Transport and Use of RTP in WebRTC
- RFC 8835: Transports for WebRTC
- RFC 9429: JavaScript Session Establishment Protocol (JSEP)
- RFC 9725: WebRTC-HTTP Ingestion Protocol (WHIP)
- IETF datatracker: RFC 9725
- IETF datatracker: draft-ietf-wish-whep (WHEP)
- IETF datatracker: RFC 5764 (updated by RFC 7983 and RFC 9443)
- IETF datatracker: RFC 8445 (updated by RFC 8863)
- coturn README.turnserver
- coturn example turnserver.conf
- coturn README.turnutils
- Chrome Enterprise policy list (WebRtcIPHandling, WebRtcLocalIpsAllowedUrls, WebRtcUdpPortRange)
- Microsoft Edge policy: WebRtcLocalhostIpHandling
- Microsoft Edge policy: WebRtcLocalIpsAllowedUrls
- Microsoft Edge policy: WebRtcUdpPortRange
- Microsoft Learn: reg query
- ss(8) Linux manual page
Last reviewed: 23 October 2026. Browser WebRTC policies and coturn defaults change between releases; confirm against the documentation for the versions you run.