When visiting some websites like http://www.monip.org or http://ip-api.com, I get the following result:

Your current IP Address
 - IP:    197.158.x.x
 - Internal IP:    192.168.x.x

I understand that I can see my public IP address (197.158.x.x). What I can't figure out is that how come my internal IP address is visible through the Internet?

Those websites do not seem to use a Flash plugin, Java applet or other scripts. My ISP is performing a NAT of my internal IP address in order to access the Internet:

3G Wireless Modem [192.168.x.x] -------- ISP [NAT to 197.158.x.x] ------- Internet

So how is it possible for a website to see my internal IP address?

  • 2
    I looked at the network traffic and noticed the page generating STUN requests. It generated STUN requests from both my local IP addresses. The page displayed both my local IP addresses even though the STUN requests only worked for one of them. – kasperd Jul 24 '15 at 10:42
  • 4
    What's interesting is that only ip-api.com gives my internal IP address, not monip.com. For me anyway. – RoraΖ Jul 24 '15 at 11:26
  • 21
    Because Mozilla&co don't give a damn about your privacy. They prefer Firefox silently acting as spyware over bothering the user with a prompt. – CodesInChaos Jul 25 '15 at 11:27
  • 7
    @CodesInChaos Fun fact! The Mozilla employee blocking attempts to fix the problem there, Eric Rescorla, also worked with the NSA to on their "Extended Random" modifications (backdoor) for Dual Eliptic Curve, which sought to make the crypto orders of magnitude easier to crack. – Boann Jul 26 '15 at 19:25
  • 6
    @Boann Didn't he co-author about every second TLS related RFC? So the NSA related RFCs might just be by-products of his generally high TLS related activity. – CodesInChaos Jul 26 '15 at 19:56
up vote 109 down vote accepted

The most likely source of this information is your browser's WebRTC implementation.

You can see this in the source code of ip-api.com.

From https://github.com/diafygi/webrtc-ips, which also provides a demo of this technique:

Firefox and Chrome have implemented WebRTC that allow requests to STUN servers be made that will return the local and public IP addresses for the user. These request results are available to javascript, so you can now obtain a users local and public IP addresses in javascript.

It was recently noted that the New York Times was using this technique to help distinguish between real visitors and bots (i.e. if the WebRTC API is available and returns valid info, it's likely a real browser).

There are a couple of Chrome extensions that purport to block this API, but they don't seem to be effective at the moment. Possibly this is because there aren't yet the hooks in the browser, as that GitHub README alludes to:

Additionally, these STUN requests are made outside of the normal XMLHttpRequest procedure, so they are not visible in the developer console or able to be blocked by plugins such as AdBlockPlus or Ghostery.

  • 56
    It's a real sad state of affairs that browser makers are shoveling so many of these new and untested APIs into browsers without giving a damn bit of thought for the privacy damage. – Boann Jul 24 '15 at 16:18
  • 2
    The real question is, why would you ever want that for a legitimate purpose (other than telling it to the user, I suppose)? – Schilcote Jul 24 '15 at 21:05
  • 14
    @Schilcote In-browser VoIP or videoconferencing? But the way they've done this, with no way to disable it, is frightening. – Michael Hampton Jul 25 '15 at 0:26
  • 3
    Disable WebRTC is a Firefox add-on that prevents LAN IP leakage. – Adam Katz Jul 25 '15 at 0:40
  • 5
    Are there privacy implications to some third party knowing your NATted private IP? I would have thought this would be of little meaning to someone outside your network. – rakslice Jul 27 '15 at 1:28

A common method to get the internal IP address is by using RTCPeerConnection in JavaScript.

http://ip-api.com/ for example, is calling a javascript function named "gi" that contains the following code:

...
 o = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection,
...

Technically, this is done by setting a callback on the RTC Connection (object o) with "onicecandidate" and getting the attribute candidate.candidate from the event. This will list all the local IP addresses of your network interfaces.

Take a look at Module: Get Internal IP WebRTC.

The JavaScript script can send this information back to an Internet server, but http://ip-api.com/, as an example, is just displaying it to the client.

WebRTC is only one of several ways that LAN IP addresses can be discovered.

There was a nice Black Hat 2012 talk on this topic, called Blended Threats and JavaScript: A Plan For Permanent Network Compromise, in which Phil Purviance and Josh Brashars presented an automated method to find and wipe your home wifi router with a single click on a website.

Blended Threats and JavaScript

This predated WebRTC, so they had to discover your router's IP address in another way. This can be done with JavaScript scanners like jslanscanner, JSScan, JS-Recon, but a simple (yet large) collection of embedded objects that merely guess at the router's address (e.g. by embedding an expected router image and noting when it successfully loads). Once you've got the address, you can guess the password (starting with the expected default) using RouterPasswords.com or even bypassing authentication via Routerpwn.com.

As a proof of concept, their demonstration discovered the router IP, looked up its default password, logged in, and automatically installed replacement firmware (DD-WRT). A real attack could have any number of malicious capabilities on the new firmware and could easily make it appear to be the unmodified original router system.

(Admittedly, this identifies your home wifi router's LAN IP address rather than your local LAN IP address, but it's pretty close and arguably more alarming.)

Most likely, your browser (or your ISP) is sending an X-Forwarded-For header that reveals your internal IP address. Check a site like this one to see what headers you're sending.

  • 3
    I wouldn't have thought my ISP would have that information either. The browser probably correct though. – Ash Burlaczenko Jul 24 '15 at 9:41
  • If they are the ones doing the NATing (or, more likely in your case, proxying), they MUST have that information in order to send back the answer from the server. – Stephane Jul 24 '15 at 10:25
  • 4
    I tested the links, and this is not what is happening. No X-Forwarded-For header is being sent, and the second link still manages to find the local IP addresses. – kasperd Jul 24 '15 at 10:29
  • 2
    This is not how NAT works. You're confusing concepts. -1 – Lightness Races in Orbit Jul 26 '15 at 18:58
  • 5
    @LightnessRacesinOrbit, that's not how NAT works, but I never said NAT. A transparent proxy will add the headers just fine. – Mark Jul 26 '15 at 19:32

The first of your two links did not work for me but the second did. On viewing the JavaScript code of the second link, I found that it is using window.RTCPeerConnection.

Not all browsers support RTCPeerConnection, but in those that do it can be used to identify the local IP addresses of the browser. This answer on Stack Overflow gives an example of how the asynchronous API of RTCPeerConnection can be used to find a local IP address.

  • 1
    This seems to have a lot of overlap with an earlier-posted answer. I wonder if the last sentence might be more useful as an edit to one of the existing answers rather than a new answer? – D.W. Jul 24 '15 at 19:26
  • @D.W. At the time I posted only three answers were visible to me. And none of them mentioned RTCPeerConnection. I have no idea why those other two answers were not shown to me at the time. – kasperd Jul 24 '15 at 19:31
  • Cool! System glitch, maybe; who knows. Anyway, thanks for the link to SO; good stuff. – D.W. Jul 24 '15 at 19:33

It's likely the site is hosting some JavaScript that is running on your machine and figuring out your internal address and putting it on the screen.

The remote server won't see your internal address and it's unlikely to be forwarded in a HTTP header.

  • 3
    This might be correct. But how would javascript code be able to find the IP address of the host it is running on? – kasperd Jul 24 '15 at 10:31
  • I believe that this particular page won't see the local IP addresses. But if it is visible to javascript, then any site can include javascript which will send it back to the server. – kasperd Jul 24 '15 at 10:43
  • @kasperd This is possible through javascript, there is a proof of concept here – BadSkillz Jul 24 '15 at 11:05
  • You can use WebRTC in JavaScript to accomplish this. Another demo Here – kevino_17 Jul 24 '15 at 11:12

The underlying TCP/IP protocol won't be disclosing your internal address - it isn't used for routing across the public internet and isn't captured/stored in the protocol packets themselves at layer 3 as the packets are created by your perimeter router. Any number of services or clients you are running may be disclosing this in layer 7 in headers, service banners, etc.

The definitive way of finding out what is leaking this info is to use a network traffic dumping program on your internal network (like wireshark or tcpdump) and check the contents of the packets at layer 7 i.e. the data payload, and if the internal address not being recorded somewhere in the data payload by your client then it will probably be coming from your perimeter router (though this is unlikely) and you will need to capture the network traffic on the internet side of the router somewhere to see how this is happening.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.