Before getting to the juicy part of this article, you need to understand why WebRTC requires your IP address and how this is not technically a vulnerability as much as a feature of WebRTC.
We’ll explore:
- Attack vectors that demonstrate how WebRTC can be exploited
- The privacy implications of a leaked IP address
- How to protect yourself, and whether you even need to
Why Does WebRTC Need My IP Address?
An IP (Internet Protocol) address helps route data around networks. Each device is assigned a unique IP address that can be used to identify it. An IP address can either be local or public, a local address is used to communicate with local devices on the same LAN (local area network), while a public address is used to communicate with devices over the internet.
How WebRTC works and how it determines the optimal route to connect two or more devices is quite complicated. For the purposes of this article, let’s just assume that establishing a connection is a matter of exchanging connection information (IP addresses) between peers. This connection information is referred to as ICE (Interactive Connectivity Establishment) candidates, a standard method of NAT (Network Address Translation) traversal used in WebRTC, which shows the available methods the peer can communicate through (directly or through a TURN server).
There are three types of addresses that a WebRTC client tries to negotiate:
- Local IP addresses
- Public IP addresses found through STUN servers
- Public IP addresses found through TURN servers.
For peers to establish an optimal connection, this information is needed. For example, if two devices are connected to the same local network, they need access to each other’s local IP addresses. While if they’re not on the same network, they will need an accessible public IP.
With modern browsers and the growing need to access resources such as devices’ webcams and microphones, an easy-to-use API was needed. This is where WebRTC came in, a JavaScript library built into modern browsers and enabled by default.
It provides a convenient API for developers to interact with and makes it easy to create a media connection between multiple peers. Part of this ease-of-use requires a way to retrieve the ICE candidates for the local device, as that information must be shared with any other peer to create a connection. As such, WebRTC exposes a convenient way to access ICE candidates and, indirectly, an easy way to access a device’s local and public IP address.
NAT: Private and Public IP Addresses
IPv4 was introduced in 1983, and its 32-bit format only allows for ~4.3 billion unique addresses. Today we have more than that number of unique devices connected to the Internet, meaning each device cannot have a unique public IP address.
NAT is a method adopted by Firewalls and routers to map multiple local private IPv4 addresses to a public IPv4 address before transferring the information, which conserves public IPv4 addresses that are legally registered.
This means that when you connect your phone or laptop to the Internet, you’re not getting a unique public IPv4 address; instead, you’re using the router's public address or your ISPs (Internet Service Provider).
The successor to IPv4 is IPv6, and you can read more here. With the introduction of IPv6, NATs (for its original intention) will no longer be needed, as it will be possible for each device to have a unique IP address.
As IPv6 is newer and not fully adopted, this article will discuss the implementation of an IP leak in the context of IPv4, how big of a concern it is to leak either your public or private IPv4 address and what it means if you leak both.
Accessing IP Information Through WebRTC JavaScript
The local IP address can be easily extracted from an ICE candidate:
12345678const pc = new RTCPeerConnection(); pc.onicecandidate = e => { if (e.candidate) { console.log(e.candidate.candidate.split(" ")[4]); } } pc.createOffer({offerToReceiveAudio: true}) .then(offer => pc.setLocalDescription(offer));
It should be noted that the above can be executed on any website and will work as long as WebRTC is not manually disabled in the browser (enabled by default). More importantly, there is no prompt for the above code; this can be executed and will not be visible to the user.
However, if you were to run the above in 2022, you may note that it does not actually print out your local IP address. Instead, it’ll look something like this:
e6d4675b-0c93-43d1-b4be-f8ae4d050721.local
This is an mDNS address, and it solves the problem of leaking local IP addresses through WebRTC.
What Is mDNS (Multicast DNS)
The Domain Name System (DNS) is used to resolve a domain name, for example, https://google.com, to an IP address. Similarly, the mDNS protocol resolves hostnames to IP addresses within small networks that do not include a local name server.
However, it works slightly different because there is no registry to check the match between the hostname and an IP address. Instead of querying a name server, all participants in the network are directly addressed. When a client wants to know the IP address within the local network of a device with a given name (say gordon.local), it sends a multicast into the network and asks which network participant matches up with the hostname. All devices in the local network receive the request, and the device with the correct name can then return its IP address, also over multicast.
All devices on the local network receive the response and can now cache that information for future use.
How WebRTC Uses mDNS
As previously mentioned, WebRTC tries to connect peers in the most optimal way. To maximize the probability of a direct peer-to-peer connection, client private IP addresses are included in the ICE candidate collection, for example, when two devices are on the same local network and need to connect.
However, exposing the local IP address to any malicious JavaScript running in the browser can have privacy implications - and, as we will later see, can also be used for more advanced exploits.
Which is why WebRTC now uses mDNS. The local IP address is concealed with dynamically generated mDNS names. This is handled for you automatically - if WebRTC needs to share a local IP address that it considers private, it will use an mDNS address instead. If there is no mDNS address, it will generate and register a random one with the local network.
This random address will be used as a replacement for the local IP address in all SDP and ICE message negations. This ensures that the local IP address isn’t exposed to JavaScript, and additionally, the local IP address isn’t exposed to signaling or other servers.
Abusing the WebRTC Library
Famously, back in 2015, it came out that the New York Time website used WebRTC without any legitimate use for it. Articles came out criticizing the website for gathering IP addresses. This was supposedly for click fraud tracking and bot identification. This is only one example of countless others.
Interesting observations can be made by looking at Google’s anonymous usage statistics from Chrome through the Chrome Platform Status.
Looking at the percentage of page loads WebRTC is initialized, the number is quite large ~6-8%:
This graph shows the percentage of RTCPeerConnection
calls on Chrome page loads.
This only shows WebRTC being initialized and not used. There could be legitimate reasons for this, or it could be that 6-8% of all page loads are video calls or simply bad code that is unnecessarily using the API.
What is interesting in the author’s opinion is that Covid did not seem to significantly impact the number of page loads that require a WebRTC connection. If anything, it has steadily decreased since the start of Covid.
More interesting data is looking at the calls to setLocalDescription
, which we saw previously can be used to access the local IP of a device (not as big of a concern with up-to-date browsers using mDNS).
This graph follows a similar pattern to what we saw before. However, the usage is closer to ~2-4%. Why is there such a big difference compared to the usage of the constructor? That is unclear, maybe it’s just bad code.
To complete the picture, though, we also need to take a look at the call to setRemoteDescription
, as this is needed for WebRTC to establish a peer-to-peer connection and could be considered “legitimate” use.
This graph is by far the most interesting. This is a significant difference from what we saw before, with usage being a fraction compared to the other calls, at around 0.01-0.04% of all page loads. And interestingly, here we can see that it closely follows what we would expect with the Covid pandemic, with an increase in video calls followed by a steady decrease as people return to their office or school.
This article is not attempting to make any assumptions out of this data. It is merely shared out of curiosity and to note that a significant percentage of the RTCPeerConnection
calls is potentially used for a purpose other than what WebRTC was designed for. For additional information, take a look at this article and this video. It could be that WebRTC is being misused in an attempt to gather information about the user visiting.
Real-World Attack Vector: NAT Slipstreaming
An interesting attack, named NAT Slipstreaming and discovered by Samy Kamkar, allows an attacker to remotely access any TCP/UDP service bound to any system behind a victim’s NAT, bypassing the victim’s NAT/firewall, just by visiting a website.
This article won’t go into detail on how the attack works. However, this attack is an excellent example to illustrate some of the dangers of exposing an IP address. The PoC for this attack relies on WebRTC to retrieve a victim’s local IP address. Other techniques are employed if the private address can not be retrieved through WebRTC. The attack also leverages other behaviors of WebRTC and the TURN protocol to enable it to work under additional circumstances.
For more information, see the original article by Samy Kamkaror, or this video by Hussein Nasser.
Privacy Concern: Hiding Your Identity
You’ve probably seen all the VPN (Virtual Private Network) ads encouraging you to “stay save” and hide your identity. The general idea is that you don’t want to share your public IP address while browsing the internet. There are many reasons why you might want to use a VPN:
- Access internal company resources only available through VPN
- Hide traffic from your ISP
- Avoid personalized ads and Google search results based on your IP
- Added security/encryption
- Trick websites into thinking you’re from a different region (access region-locked Netflix content, for example)
But this begs the question, is it really that bad to leak your public IP? Does a VPN really provide added security?
The answer to that is: it depends. For the most part, using a VPN will obscure your traffic from your ISP and provide you with a different IP address. However, now your just changing the entity that has control. If you trust the VPN you’re connecting to more than your ISP, then it is probably a good trade. However, there are local laws and jurisdictions that ISPs and VPNs need to adhere to. It requires research to determine who to trust and will be dependent on where you live and which services you use.
Watch this video, I Leaked My IP Address by LiveOverflow, for an excellent discussion on this topic:
- Should you be concerned about leaking your public IP address
- Should you use a VPN
- Does IPv6 change everything
Some key takeaways from the video are:
- Your public IP is (most likely) shared by many people. It could be that your home router is directly connected to the internet and is accessible through a public IP address, but it’s likely that you’re behind an additional NAT at the ISP layer.
- You could likely have a rolling IP address, meaning it changes frequently.
- Scanning the whole IPv4 subset won’t take an attacker long, and if they wanted to scan for router security issues across the whole range, they could, and your IP can be discovered regardless.
- You’re more likely to leak sensitive information through social media than the IP you’re connected to.
That all said, there are still legitimate reasons for hiding your IP address.
Can a VPN Protect You From WebRTC IP Leaks?
The answer to this question is also: it depends. Here it depends on the actual VPN and whether you have a browser extension installed or not. You should research your VPN provider to determine whether they employ techniques to obscure your “real” IP address from WebRTC and test if it works.
This article discusses how WebRTC can leak your IP even when using a VPN. The article also mentions tests you can do to see if your VPN properly hides your IP.
How To Protect Yourself
Or the bigger question: do you need to hide your public IP?
That is ultimately up to you to decide whom you trust more: VPN, ISP, or an alternative solution, such as TOR.
There are a few things to consider:
- Your VPN may not mask your real IP and could leak it through WebRTC or some other means.
- Your VPN is just as likely to log your traffic and sell it to advertisers as your ISP is.
- Your country's laws need to be taken into account.
- It is possible to disable WebRTC on all browsers (not easy to do on Chrome and requires an extension to be installed).
- Arguably, the most secure way to mask your online identity is using TOR (with the TOR browser that disables WebRTC). This exposes other risks to consider.
Make sure to research, understand the risks and trade-offs, and do some testing to ensure your chosen solution works as intended and meets your internet privacy needs.