# Neither Denied nor Exposed: Fixing WebRTC Privacy Leaks
## 4 IP Disclosure
### Problem Statement  
Bear in mind that there are two possible ways for the browser to execute a piece of JavaScript code on a webpage: (a) either immediately in the order it appears or (b) wait for a triggered event to be executed. In any case, injected JavaScript code will always be executed transparently in the background without the user's permission. Taking this into account, a webpage that supports WebRTC will execute some WebRTC API calls in the background and will try to initiate a call to the specified remote party. A code snippet responsible for such an action is given in Listing 3. This small piece of JavaScript code actually configures the STUN server that will be used for the initiation of the call and then constructs an _RTCPeerConnection_ object, which executes the STUN or TURN requests. Specifically, the code first initializes a JavaScript object with a list of possible ICE servers that could be used during the procedure, adding for each candidate the IP/domain of the server and the user's password, if needed (lines 2 to 4). As observed, in line 3, the URI scheme \"stun\" is used, followed by the server domain, while the credential field in line 4 carries the authentication password. In most cases, the selected STUN server will be one of the available servers that are offered by organizations like Google, e.g., stun.l.google.com:19302. In lines 7 to 8, the RTCPeerConnection object gets instantiated and saved in the \"servers\" variable. The \"onicecandidate\" in line 11 is an _EventHandler_, where a function is specified and it is called when an \"icecandidate\" event occurs, namely, when an ICE candidate is discovered. This is the function via which the caller/callee will retrieve any information about themselves, namely any local or external IPs they are using. Finally, the \"createDataChannel\" function in line 20 creates a new communication channel with the callee, over which any data can be transmitted. On the other hand, the \"createOffer\" function in line 22 initializes an SDP offer, with the purpose of creating a WebRTC connection with the callee. After the JavaScript code is executed, the peer will communicate with the declared STUN server and exchange data with it. ```
1//initializelistofICEservers
2 varservers={iceServers:
3[{url:\"stun:stunserver.org\",
4\"credential\":\"my_password\"}]};
5
6//constructanewRTCPeerConnection
7 varrtc=newRTCPeerConnection(
8 servers);
9
10//EventHandlerfornewICEcandidate
11 rtc.onicecandidate=function(ice){
12 if(ice.candidate){
13//ReturnsaDOMStringdescribing
14//thecandidateindetail
15 console.log(ice.candidate.candidate);
16};
17};
18
19//createabogusdatchannel
20 rtc.createDataChannel(\"\");
21//createanoffersdp
22 rtc.createOffer(function(result){
23//triggerthestunserverrequest
24 rtc.setLocalDescription(result,
25 function(){},function(){});
26},function(){});
```  
Listing 3: Initializing a WebRTC call. However, setting up and running a STUN server is a task that even a script-kiddie can easily perform aiming to expose the IP addresses of any user who executes the JavaScript code in Listing 3. Thus, if one installs a STUN server on the \"malicious_stun_server.org\" domain, they could easily replace lines 2 to 4 of Listing 3 with lines in Listing 4. ```
1 varservers={iceServers:[{url:\"stun:[EMAIL_ADDRESS]\",
2\"credential\":\"my_password\"}]};
```  
Listing 4: Choosing the preferred STUN or TURN server. By doing so, the attacker is able to force the caller's browser to use a STUN or TURN server controlled by them. Now, the aggressor could inject the script in the source code of a webpage that they own or have compromised, and as a result any browser visiting this page will gain executing a STUN request to the STUN server controlled by the attacker. For instance, think of a watering hole variant attack scenario or the use of specially selected advertisements displayed to the victim. Accordingly, any webpage containing the JavaScript code of Listing 3 and the corresponding STUN server can instantly acquire the public IP:port of the peer.