Do you own an Android device? Is it less than three years old? If so, then when your phone's screen is off and it's not connected to a Wi-Fi network, there's a high risk that it is broadcasting your location history to anyone within Wi-Fi range that wants to listen.
This location history comes in the form of the names of wireless networks your phone has previously connected to. These frequently identify places you've been, including homes ("Tom's Wi-Fi"), workplaces ("Company XYZ office net"), churches and political offices ("County Party HQ"), small businesses ("Toulouse Lautrec's house of ill-repute"), and travel destinations ("Tehran Airport wifi"). This data is arguably more dangerous than that leaked in previous location data scandals because it clearly denotes in human language places that you've spent enough time to use the Wi-Fi. Normally eavesdroppers would need to spend some effort extracting this sort of information from the latititude/longitude history typically discussed in location privacy analysis. But even when networks seem less identifiable, there are ways to look them up.
We briefly mentioned this problem during our recent post about Apple deciding to randomize MAC addresses in iOS 8. As we pointed out there, Wi-Fi devices that are not actively connected to a network can send out messages that contain the names of networks they've joined in the past in an effort to speed up the connection process. But after writing that post we became curious just how many phones actually exhibited that behavior, and if so, how much information they leaked. To our dismay we discovered that many of the modern Android phones we tested leaked the names of the networks stored in their settings (up to a limit of fifteen). And when we looked at these network lists, we realized that they were in fact dangerously precise location histories.
Aside from Android, some other platforms also suffer from this problem and will need to be fixed, although for various reasons, Android devices appear to pose the greatest privacy risk at the moment.
In Android we traced this behavior to a feature introduced in Honeycomb (Android 3.1) called Preferred Network Offload (PNO). PNO is supposed to allow phones and tablets to establish and maintain Wi-Fi connections even when they're in low-power mode (i.e. when the screen is turned off). The goal is to extend battery life and reduce mobile data usage, since Wi-Fi uses less power than cellular data. But for some reason, even though none of the Android phones we tested broadcast the names of networks they knew about when their screens were on, many of the phones running Honeycomb or later (and even one running Gingerbread) broadcast the names of networks they knew about when their screens were turned off.
Response from Google
When we brought this issue to Google's attention, they responded that:
"We take the security of our users' location data very seriously and we're always happy to be made aware of potential issues ahead of time. Since changes to this behavior would potentially affect user connectivity to hidden access points, we are still investigating what changes are appropriate for a future release."
Additionally, yesterday a Google employee submitted a patch to wpa_supplicant which fixes this issue. While we are glad this problem is being addressed so quickly, it will still be some time before that fix gets integrated into the downstream Android code. And even then, Android fragmentation and the broken update process for non-Google Android devices could delay or even prevent many users from receiving the fix. (We hope Google can make progress on this problem, too.)
Protective Steps You Can Take Today
With that said, a workaround is available (for most devices) for users who want to protect their privacy right now: go into your phone's "Advanced Wi-Fi" settings and set the "Keep Wi-Fi on during sleep" option to "Never". Unfortunately this will cause a moderate increase in data usage and power consumption—something users shouldn't have to do in order to keep their phone from telling everyone everywhere they've been.
Unfortunately, on at least one device we tested–a Motorola Droid 4 running Android 4.1.2–even this wasn't sufficient. On the Droid 4, and perhaps on other phones, the only practical way to prevent the phone from leaking location is to manually forget the networks you don't want broadcast, or disable Wi-Fi entirely whenever you aren't actively connecting to a known Wi-Fi network. You can also find apps that will do this automatically for you.
Location history is extremely sensitive information. We urge Google to ship their fix as soon as possible, and other Android distributors to offer prompt updates containing it.
This capability is also necessary in order to connect to "hidden" networks, because those networks don't broadcast their existence like normal Wi-Fi networks. Instead, the phone or other device has to send out a message essentially asking "Are you there?" and if the hidden network is nearby, it will respond.
In our testing no iOS 6 or 7 devices were affected, though we observed the same problem on one of several tested iOS 5 devices (an iPad), and earlier versions of iOS might or might not be affected. Many laptops are affected, including all OS X laptops and many Windows 7 laptops. Desktop OSes will need to be fixed, but because our laptops are not usually awake and scanning for networks as we walk around, locational history extraction from them requires considerably more luck or targeting.
The offending code is actually in an open source project called wpa_supplicant, which many Linux distributions, including Android, use to manage Wi-Fi. We want to give credit to Android developer Chainfire as well as several others on the XDA forums whose posts on this behavior were very informative. A couple of other researchers have previously critiqued this behavior.
The list of phones we tested is available as a CSV file or a Google Doc.
Note that this method isn't foolproof, since an attacker might still be able to get your phone to transmit its known network list when it is connected by transmitting a packet that temporarily disconnects you. Then, depending on the timing, your phone may send the list of networks before it reconnects.