The “IP Address Leakage” topic has turned into a public relations issue for WebRTC. It is a fact that the WebRTC API’s can be used to share one’s private IP address(es) without any user consent today. Nefarious websites could potentially use this information to fingerprint individuals who do not want to be tracked. Why is this an issue? Can this be stopped? Can I tell when someone is trying to use WebRTC without my knowledge? We try to cover those questions below along with a walkthrough of a Chrome extension that you can install or modify for yourself that provides a notification if WebRTC is being used without your knowledge.
The “IP Leakage” problem
Why does WebRTC need a local IP address?
As Reid explained long ago in his An Intro to WebRTC’s NAT/Firewall Problem, peer-to-peer communications cannot occur without providing the peer your IP address. The ICE protocol gathers and checks all the addresses that can be used to communicate to a peer. IP addresses come in a few flavors:
- host IP address – this is the usually the local LAN IP address and is the one that is
being exposed that is causing all the fussnot usually exposed - server-reflexive – this is the address outside the web server hosting the page will see
- relay – this will show-up if you have a TURN server
Why not just use the server reflexive and relay addresses? The host IP address is the If you have 2 peers that want to talk to each other on the same LAN, then the most effective way to do this is to use the host IP address to keep all the traffic local. Otherwise you might end up sending the traffic out to the WAN and then back into the LAN, adding a lot of latency and degrading quality. This is the best address to use for this situation.
In addition, there are scenarios where one might want to hide their server-reflexive IP addresses too. As it is currently implemented, the ICE process gathers all the IP address it can find. If you are using a Virtual Private Network (VPN), you may want only want WebRTC traffic coming over that VPN IP address. If you are a political dissident in an oppressive state that controls the ISPs and monitors web traffic, then leaking your public IP address to your ISP while using a service like Tor could expose your identity.
Relay addresses require that you setup a TURN server to relay your media. Use of relay means you are no longer truely peer-to-peer. Relay use is typically temporarily to speed connection time or as a last resort when a direct peer-to-peer connection cannot be made. Relay is generally avoided since just passing along a lot of media with no added value is expensive in terms of bandwidth costs and added latency.
This is why the WebRTC designers do not consider the exposure of the host IP address a bug – they built WebRTC on this way on purpose. The challenge is this mechanism can be used in to help with fingerprinting, providing a datapoint on your local addresses that you and your network administrator might not be happy about. The concern over this issue is illustrated by the enormous response on the Dear NY Times, if you’re going to hack people, at least do it cleanly! post last month exemplified this issue.
Why not just ask for when someone wants your local IP address?
When you want to share a video or audio stream, a WebRTC application you use the getUserMedia API. The getUserMedia API requires user consent to access the camera & microphone. However, there is no requirement to do this when using a dataChannel. So why not require consent here?
Let’s look at the use-cases. For a typical WebRTC videochat, user consent is required for the camera permission. The question “do you want to allow this site to access to your camera and microphone” is easy to understand for users. One might require consent here or impose the requirement that a mediastream originating from a camera is attached to the peerconnection.
What about a webinar. Participants might want to join just to listen. No permission is asked currently. Is that bad? Well… is there a permission prompt when you connect to a streaming server to watch a video? No. What is the question that should be asked here?
There are usecases like filetransfer which involve datachannel-only connections without the requirement of local media. Since you can upload the file to any http server without the browser asking for any permission, what is the question to ask here?
Last but not least, there are usecases like peer-to-peer CDNs where visitors of a website form a CDN to reduce the server-load in high-bandwidth resources like videos. While many people claim this is a new use-case enabled by WebRTC, Adobe showed this capability in Flash at MAX 2008 and 2009.
As as side-note, the RTMFP protocol in Flash has leaked the same information since then. It was just alot less obvious to acquire.
There is an additional caveat here. Adobe required user consent before using the user’s upstream to share data — even if peer-to-peer connections did not require consent. Apparently, this consent dialog completely killed the use-case for Flash, at a time when it was still the best way to deliver video. What is the question that the user must answer here? And does the user understand the question?
Photo courtesy flickr user Nisha A under Creative Commons 2.0
What are the browser vendors and the W3C doing about it?
Last week Google created an extension with source code to limit WebRTC to only using public addresses. There have been some technical concerns about breaking applications and degrading performance.
Mozilla is considering similar capabilities for Firefox as discussed here. This should hit the nightly build soon.
The W3C also discussed the issue at their recent meeting in Berlin and will likely address this as part of the unsanctioned tracking group.
How do I know if a site is trying to run WebRTC?
We usually have chrome://webrtc-internals open all the time and occasionally we do see sites using WebRTC in unexpected ways? I wondered if there was an easier way to see if a site was covertly using WebRTC, so I asked Fippo how hard it would be to make an extension to show peerConnection attempts. In usual fashion he had some working sample code back to be in a couple of hours. Let’s take a look…
How the extension works
The extension source code is available on github.
It consists of a content script, snoop.js, which is run at document start (as specified in the manifest.json file) and a background script, background.js
The background script is sitting idly and waiting for messages sent via the Message Passing API.
When receiving a message with the right format, it prints that message to the background page’s console and show the page action.
1 2 3 4 5 6 7 |
chrome.runtime.onConnect.addListener(function (channel) { channel.onMessage.addListener(function (message, port) { if (message[0] !== 'WebRTCSnoop') return; console.log(new Date(), message[1], message[2]); chrome.pageAction.show(port.sender.tab.id); }); }); |
Pretty simple, eh? You can inspect the background page console from the chrome://extensions page.
Let’s look at the content script as well. It consists of three blocks.
The first block does the important work. It overloads the createOffer, createAnswer, setLocalDescription and setRemoteDescription methods of the webkitRTCPeerConnection using a technique also used by adapter.js. Whenever one of these methods is called, it does a window.postMessage which is then triggers a call to the background page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var inject = '('+function() { // taken from adapter.js, written by me ['createOffer', 'createAnswer', 'setLocalDescription', 'setRemoteDescription'].forEach(function(method) { var nativeMethod = webkitRTCPeerConnection.prototype[method]; webkitRTCPeerConnection.prototype[method] = function() { // TODO: serialize arguments var self = this; this.addEventListener('icecandidate', function() { //console.log('ice candidate', arguments); }, false); window.postMessage(['WebRTCSnoop', window.location.href, method], '*'); return nativeMethod.apply(this, arguments); }; }); }+')();'; |
The code snippet also shows how to listen for the ice candidates in a way which
The second part, inspired by the WebRTCBlock extension, injects the Javascript into the page by creating a script element, inserting the code and removing it immediately.
1 2 3 4 |
var script = document.createElement('script'); script.textContent = inject; (document.head||document.documentElement).appendChild(script); script.parentNode.removeChild(script); |
Last but not least, a message channel is set up that listens to the events generated in the first part and send them to the background page:
1 2 3 4 5 6 |
var channel = chrome.runtime.connect(); window.addEventListener('message', function (event) { if (typeof(event.data) === 'string') return; if (event.data[0] !== 'WebRTCSnoop') return; channel.postMessage(event.data); }); |
There is a caveat here. The code is not executed for iframes that use the sandbox attribute as described here so it does not detect all usages of WebRTC. That is outside our control. Hey Google… can you fix this?
Ok, but how do I install it?
If you are not familiar with side-loading Chrome extensions, the instructions are easy:
- Download the zip from github
- Unzip it to a folder of your choice
- go to chrome://extensions
- Click on “Developer mode”
- Then click “Load unpacked extension”
- Find the webrtcnotify-master folder that you unzipped
That’s it! If you want to see more details from the extension then it is helpful to load the extension’s console log. To do this just click on “background page” by “Inspect views”.
If you are familiar with Chrome Extensions and have improvement ideas, please contribute to the project!
What do I do if I find an offending site?
No one really knows how big of a problem this is yet, so let’s try to crowd source it. If you find a site that appears to be using WebRTC to gather your IP address in a suspicious way then post a comment about it here. If we get a bunch of these and others in the community confirm then we will create a public list.
With some more time we could potentially combine selenium with this extension to do something like a survey of the most popular 100k websites? We are not trying to start a witch hunt here, but having data to illustrate how big a problem this is would help inform the optimal path forward enormously.
{“authors”: [“Chad Hart“, “Philipp Hancke“]}
Editor note – 6 Aug, 2015: we neglected to cover the implications of exposing a public IP address. We added a short paragraph on this in brown text to the “Why does WebRTC need a local IP address?” section. {“editor”: “Chad Hart“}
Olivier de Jong says
I think the whole “IP Address Leakage” story requires some context. To me it is a non-issue and not really a privacy hog.
I always get annoyed with the fact that people using a browser are so concerned with privacy isues and that when that browser is a webview with an icon nothing is a problem. A browser is nothing more than a piece of software, like an app or an installed program. So why treat it differently?
Furthermore another popup for permission to find an ip address? My camera? The delete button? come on! My facebook app can control my cam and mic without my consent at any time and then some..
If we look at the future of web, apps and programs I think we need to be a bit more concerned about user experience instead of creating pop-ups..
Private says
When exposing your IP means torture or even death at some places, you won’t care much for… “user experience”.
I’m impressed by how ignorant one can be. If it doesn’t affect you, then there are millions who consider this a life threatening issue.
And yes, “Millions”.
Olivier de Jong says
I was pointing to the stupid “i want my privacy” rants when web browsing. If the same webpage is packaged as an app or program then the rants all of a sudden stop and everything is fine.
If one is concerned about privacy one should use stuff like tor. Ignorance is bliss..
lynX says
> Nefarious websites could potentially use this information to fingerprint individuals who do not want to be tracked.
That is not the main concern. Nefarious websites could systematically gather which visitors are using VPNs or Tor… which in some countries indicates they are very probably dissidents. With the real IP address in the pockets the authorities can go visit the potential dissident and see what she or he has been up to. They will most probably find evidence on the computer since dissidents in poor countries aren’t particularely educated in operational security. Therefore a plugin that they first need to know about will not fix the problem in time. Thousands (or according to the other poster, millions) may be endangered by the introduction of WebRTC… even if these people never asked for any WebRTC in their browsers and weren’t planning to use it for anything.
Chad Hart says
We made a mistake by omitting the scenario where one would want to hide one or more of their public IP addresses while using a VPN or service like Tor. We will made an update to the post to reflect this soon after some research.
Chad Hart says
Google has modified Chrome and released an optional extension to limit IP leakage for those who want to do that: https://groups.google.com/forum/#!topic/discuss-webrtc/bMOsMFx7PFc
zy-fi says
I’ve seen this in some forumotion sites in the form of an injected encoded script. Very suspicious. It appears to be from Criteo, but that could just be its cover.
Chad says
Here is a list of sites that used WebRTC for tracking purpose from a great web crawler project: https://webtransparency.cs.princeton.edu/webcensus/webrtc_scripts.html
stan says
still work?i see no more real ip but just vpn ip on latest chrome
Philipp Hancke says
Chrome changed the ip gathering behaviour to counter some of this.