1040
April 12, 2015

Timing Side Channel "Port Scanner" in the Browser

Here is a TCP "port scanner" that works from inside your browser. It can scan your local network! Actually, it is not really a port scanner, because it can only distinguish between the following two cases:

  1. The port is open or the port is closed and responds right away with a TCP RST or ICMP Destination Unreachable packet.
  2. The port is "stealthed" or the port is open and hangs when it receives an HTTP request or there isn't a host at that IP address at all.

So it is more correct to say that it scans for the presence of a host at an IP address, but it can be used as a port scanner if all the ports of a known-to-exist host are "stealthed" except for the open ones.

The scanner works by timing how long it takes your browser to give up trying to load a nonexistent image file. If it fails fast, it's Case 1. If it fails slowly, it's Case 2. This page uses 1500 milliseconds as the cutoff time, which works well in all the testing I've done. View this page's source code to see exactly how it works.

Note: The scanner will not work if you have the NoScript Firefox extension and its ABE feature is enabled (see below). It also doesn't work with every port. For example, Firefox seems to know not to send requests to ports for other well-known services, like port 22 (SSH) or 110 (POP). At the very least, it works reliably with port 80 (HTTP) and 443 (HTTPS).

Local Network Scan (Proof of Concept)

Custom Scan

IP Address:  
Port:

Why is this a problem?

I don't think this is a very big deal, but there are a few reasons you might not want it to be possible:

  1. If you visit an attacker's website, they can use your connection to port scan another host on the Internet as part of an attack. Since the scan came from your connection, you might get blamed.
  2. Websites you visit can get a little bit of information about what you have running on your local network, which might help if they want to attack you later.

  3. If you have a highly unique local network, then it can be used as a kind of "supercookie" to help track you online. This is probably impractical because scanning takes a long time.

  4. Tor and Tails users: This scanner does not work in the Tor Browser Bundle. However it does work in Tails 1.3.2, and could potentially be used to deanonymize you.

    For example, if you have a printer with an open web administration page on your local network, a website you visit could scan your network for printers, then fingerprint them (e.g. by requesting known image URLs for common brands of printers), potentially learning the make, model, and firmware version of your printer.

    I emailed Tails about this on April 7, 2015, their response, as of May 26, 2015, is:

    My understanding is that this will be fixed once https://labs.riseup.net/code/issues/7976 is resolved. This is being worked on for Tails 1.4.1.

    Mitigation: To prevent this scanner from working in the latest version of Tails (1.3.2), simply remember to enable NoScript's ABE feature every time you boot Tails. NoScript is installed by default in Tails, but ABE is disabled for some reason.

Which browsers and operating systems are affected?

I've tested this and found it to work on the following systems:

How do I protect myself?

Unfortunately, I don't know of an easy way to stop websites from using your browser to scan the public Internet, except for turning off JavaScript. Browsers will have to add an artificial delay to make Case 1 look like Case 2.

To stop websites from scanning your local network, all your browser needs to do is deny any request from an Internet web page to a local IP address. If you use Firefox, the NoScript extension will do this for you. NoScript's main purpose is to disable JavaScript, but it has a lot of extra security features, and that is one of them. Make sure you have the Application Boundaries Enforcer (ABE) feature turned on.

I'm not aware of any Chrome or Internet Explorer extensions that block local requests. If you know of one, let me know and I will add it here.