10

Just noticed that on Chrome only, RTCIceCandidate no longer returns an IP, but rather an obfuscated address.

RTCIceCandidate 
address: "a5b3ef18-2e66-4e24-91d2-893b93bbc1c1.local"
candidate: "candidate:169888242 1 udp 2113937151 a5b3ef18-2e66-4e24-91d2-893b93bbc1c1.local 47871 typ host generation 0 ufrag 7dHv network-cost 999"
component: "rtp"
foundation: "169888242"
port: 47871
priority: 2113937151
protocol: "udp"
relatedAddress: null
relatedPort: null
sdpMLineIndex: 0
sdpMid: "0"
tcpType: ""
type: "host"
usernameFragment: "7dHv"

Notice the first property of RTCIceCanadate is "address", and "ip" is no longer part of this object.

The following code determines the local IP address of a browser. Still works on MOZ.

function discover()
{
    try{
        //Get Local IP
        window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;   //compatibility for firefox and chrome

        if (pc)
            pc.close();
        
        pc = new RTCPeerConnection({iceServers:[]});   
        pc.onicecandidate = onIceCandidate;   
        pc.createDataChannel("");   
        pc.createOffer(pc.setLocalDescription.bind(pc), noop);   
    
    } catch (e)
    { console.log(e.message);}
}

function noop()
{
}

function onIceCandidate(ice)
{   
    console.log(ice.candidate);

    if(!ice || !ice.candidate || !ice.candidate.candidate)  return;
    
    var my_ip = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];

    this.onicecandidate = noop;

    ip = my_ip.split(".")[0]+'.'+my_ip.split(".")[1]+'.'+my_ip.split(".")[2];
}

Is WebRTC officially now a fractured standard? MOZ still lists "ip" as a member of RTCIceCandidate, with no mention of the "address" member that Chrome returns.

Is there a way to de-obfusucate the mDNS address back to an ip address without forcing users to mess around with browser settings they don't understand?

Dominic Cerisano
  • 3,522
  • 1
  • 31
  • 44
  • 4
    This has been changed back in beta, but the production version of Chrome still has fractured WebRTC. The Chrome-WebRTC bug forum already has complaints from intranet service providers about this. Services as basic as network printing are now broken. – Dominic Cerisano Jun 27 '19 at 04:19
  • 2
    Thanks for raising this point. – M.Hefny Nov 12 '19 at 17:26
  • 1
    Also noticed Google is discontinuing its own network printing service "Google Cloud Print", which relies on discovering local printer IPs. – Dominic Cerisano Feb 18 '20 at 02:54
  • Firefox now also shows the obfuscated address. – Alen Siljak Mar 13 '21 at 21:09
  • The obfuscated address is mDNS, a secure address scheme to prevent fingerprinting. For most use cases this should be sufficient without exposing private IP. Just wish these standards bodies would warm up their hands before obfuscating primary API calls. – Dominic Cerisano Apr 26 '22 at 22:44

4 Answers4

7

Chrome is not broken, the WebRTC standard is evolving to prevent sites from collecting local addresses by diverting the WebRTC API. If you used this hack to obtain local addresses, you might need to find another approach.

Here are the corresponding issues for Chromium and Firefox, and the current IETF draft for WebRTC mDNS candidates.

Community
  • 1
  • 1
  • 4
    It was not a hack, it was the standard default until it was arbitrarily switched 'because security reasons'. If you had actually read the standards, you would have known that. Chrome security policies are obviously unstable and make peer-to-peer stacks like WebRTC too risky for production. My advice to devs is to avoid Chrome if possible. Don't shoot the messenger. – Dominic Cerisano Aug 03 '19 at 02:31
  • 3
    Sorry, but RFC 5245 said collecting host IP candidates is not mandatory (actually, Safari does not do it by default for IPv4). RFC 8445 even states about the private IPv4 addresses in server reflexive candidates "These MAY be omitted or set to invalid values if the agent does not want to reveal them, e.g., for privacy reasons." I'm all for avoiding Chrome and switching to Firefox actually, however note that they are implementing the same mDNS candidates standard in Firefox. – Paul-Louis Ageneau Aug 06 '19 at 10:30
4

The ip field got renamed to address in the W3C webrtc specification at some point since these days the field can contain either an IP address or a mdns hostname. What you are seeing is part of the rollout of the WebRTC host candidate obfuscation which is described ħere which is happening in Chrome 75. You can not decode this mdns hostname in the browser.

If you have a legitimate use-case you might want to ask for it to be considered in that mailing list thread.

Philipp Hancke
  • 15,855
  • 2
  • 23
  • 31
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/195611/discussion-on-answer-by-philipp-hancke-fractured-rtcicecandidate-no-longer-retu). – Samuel Liew Jun 27 '19 at 06:58
4

You can disable this feature in Chrome goto chrome:://flags and disable "Anonymize local IPs exposed by WebRTC" enter image description here

M.Hefny
  • 2,677
  • 1
  • 26
  • 30
  • 1
    This presents the same problem. Web applications that now depend on mDNS hostnames will break if this new default is disabled. What would Torvalds say about arbitrarily changing platform default policies 'because security reasons'? Does anyone really expect users to be ok with being forced to mess around with Chrome internals? – Dominic Cerisano Nov 13 '19 at 18:28
  • This link https://github.com/meetecho/janus-gateway/issues/1692 will help you. – M.Hefny Nov 13 '19 at 22:36
3

I noticed that this was happening, only returning an mDNS address (for more information about the obfuscation, read this great article completely explaining what happened).

However, I did find a new repository that seems to "fix" this (working, but not exposing the private ip, only the public). It can be found here, and the example can be found here.

divinelemon
  • 1,925
  • 2
  • 23