Android Identifiers: How Android devices and their users are identified
App reviews and security reports mention them regularly: identifiers which apps like to access. Identitifying information picked from the device and „getting transfered to somewhere“. In this context, terms like „Google Adverising ID“ or „Android ID“ are referenced.
What do they mean? And what other „identifiers“ are there? Which purposes are they supposed to serve initially – and what for are they used (or abused) in „real life“?
Background
Apps, but also many websites and other online services try to identify (and recognize) their users/visitors for different purposes like:
- Analytics: How long does a user stay on a given page or in a given app? In which order information/links are accessed, which pages/details are accessed, and which are never/rarely viewed? Primary use of this is to improve the product – but also to identify „valueable ad space“.
- Fraud protection: Whre from does a user log in to his/her account? Someone just logged in from London cannot login from Miami just minutes later. Also, a device that was never used with this account can point to fraud (think of stolen credentials).
- Collect data for trade: Creating user profiles for marketing and to sell to other companies is one of the main uses here.
The argument goes, by installing an app the user has agreed to its permissions (as to the use of cookies etc. when visiting a website) – and thus (implicitly) also to the data collection. It´s doubtful we can speak of an „educated decision“ here: exceedingly few users are aware of the scale this collection goes into, or where they might end up.
There are several properties by which a user can be uniquely identified (lets call them „identifiers“ here). Some of them are rather unproblematic – others allow to draw far-reaching conclusions about a person. Some of them can be accessed by any app or website, others are somehow „protected“ by the Android permission system. To list up and explain all of them would mean a pretty long article, so lets stick to some essentials here.
Which identifiers exist, and what´s their respective purpose?
- Device ID (also Device Serial): As most devices, Androids have a „serial number“. This number should uniquely identify a device – which is not necessarily the case with the „Device Serial“: Some noname devices (and custom ROMs) simply use
0123456789ABCDEF
(and yes, I´ve seen some of those). The Device Serial is mainly used by the Android Debug Bridge (ADB1) to distinguish between multiple connected devices: using the commandadb devices
lists them up, and one can use the-s <serial>
parameter to address a specific device. The serial can also be found via the Android device´s user interface: Settings › About device › Serial. - Device Build Fingerprint: Identifies the ROM in its specific version. Example: The Wileyfox Swift, when shipped with CyanogenOS 12.1 / Android 5.1.1) has the fingerprint
Wileyfox/Swift/crackling 5.1.1/LMY48B/YOG4PAS33J user/release-keys
. This is stored in the/system/build.prop
file, which is part of the ROMs – and thus survives a factory-reset. The fingerprint is e.g. useful to find out which exact variant of a smartphone one has at hand. - MAC: The MAC-Address identifies the corresponding network interface. Hence it is globally unique (aside maybe from some „Fakes“ and „NoName replicas“). WiFi and Bluetooth have each their own MAC address. Starting with Android-6, only system apps have access to it, all other apps just receive the default value "02:00:00:00:00:00"2; on older Android versions the permission
ACCESS_NETWORK_STATE
,ACCESS_WIFI_STATE
resp.BLUETOOTH
is required to access it (requested by ca. 70%, 30% resp. 10% of all apps).3
The MAC-Address is stored on-chip, and is needed to uniquely identify the device in a network – e.g. for the DHCP server to assign it an IP address, or to protect a network against unwanted participants (see MAC-Filter). It not only survives a factory-reset, but even system updates and ROM flashing. - IMEI: The „International Mobile Station Equipment Identity“ is a world-wide unique ID for (cellular) mobile devices (CDMA devices: MEID and its predecessor ESN). This is the „real serial number“ of the device, and usually „fixed into it“ (there are some exceptions, such as Samsung´s
/efs
partition, where it could be „accidentally wiped“). Thus it is resistant not only against a factory-reset, but also against a wipe or flashing of (custom) ROMs – ans survives all of those. On contacting the mobile provider, the IMEI is transmitted. Some network operators use this to block devices reported as stolen. If an app wants to read the IMEI, it needs the permissionREAD_PHONE_STATE
– which is requested by almost every third app. The reason given usually is to pause the app´s activities on incoming calls: wouldn´t it be annoying if your music (or video) player continues to „make noise“ – or you lose the level of your favorite game when the phone app comes to foreground? Still: technically, this is an „alleged reason“, as there are other ways for that. - IMSI: The International Mobile Subscriber Identity identifies the SIM card in GSM-, UMTS- und LTE mobile networks, and thus is stored on the same. This is a globally unique identifier – used e.g. by network providers to decide whether a device is allowed on his network and which conditions apply (tariff, roaming, etc.). As with the IMEI, apps need the permission
READ_PHONE_STATE
to access this number. Saved on the SIM card, the IMSI even survices a device change without issues. - To access the phone number, apps again need the permission
READ_PHONE_STATE
– but to find out the currently used network (MNC / MCC) they don´t need any specific permission. The same way they can also see the current „Call State“ (i.e. if there´s a call coming in or being made), as well as the state of roaming.
- The Android-ID (aka SSAID for Settings.Secure#ANDROID_ID) is automatically generated when a device is booted up for the first time, and identifies the device (or with multiple users, the currently active user on the device). Other then the GSF Android-ID (see next item) this ID exists on each and every device running Android. It is stored in a database in the local file system, and can only be accessed with root powers. A factory-reset thus destroys it – but of course a fresh SSAID is generated on the next boot.
Starting with Android 8 (Oreo), this ID stops to be global: each app will get its own SSAID, which should limit tracking across apps. - The GSF Android-ID is generated by the Google Services Framework (GSF) when it´s first initialized (usually on the first boot), and thus only exists on devices equipped with Google Apps. It is a unique identifier for all Google services (Playstore, Google Cloud Messaging (GCM), etc.), and is again stored in a database within the local file system accessible only with root powers. As its name-sake, it´s destroyed on factory-reset (see previous item).
- The Google Advertising ID (GAID) „is a unique, user-resettable ID for advertising, provided by Google Play services“. Again, this is stored in a database within the local file system, directly accessible only with root powers. But the user can manually reset it in Google Settings › Advertising. To access this ID, apps just need the permission
INTERNET
– which about 80% of them request anyway. - Hostname: This is used to identify a client (or server) in the local network. It is e.g. transmitted to an DHCP-Server when you log in to an hotspot. The user can see and change it in the developer settings.
- IP Addresses identify a device on WiFi as well as on mobile networks. They are usually assigned by DHCP-Servers. The user cannot change them (except by defining a corresponding IP range in his own WiFi router). To access IP addresses, apps need a corresponding permission:
ACCESS_NETWORK_STATE
(70%) for the mobile network resp.ACCESS_WIFI_STATE
(30%) for WiFi. - Neighboring cells and visible WiFi networks: If you´re frequently visiting the same places (like your home), you might be identified by those – though not uniquely (others might share the place). Of course your location can be roughly estimated with these data as well. While on its own this is no „unique identifier“ – connecting it with other „raw data“ (e.g. the apps installed on your device, see below) it can be pretty useful. You can only completely avoid that by switching to airplane mode.
- Configured Accounts and Email addresses are usually pretty unique (and personal). Via the permission
GET_ACCOUNTS
apps can access these: accounts generally, but in several cases also connected Email addresses, as those often identify the corresponding account (think e.g. ofjohn.doe@gmail.com
for the Google account). - Owner Info: This is the so-called „Me“ contact, which the user has to manually fill into the address book. If nothing´s deposited there, there´s nothing to gain – even if an app has the necessary permission
READ_PROFILE
. - The list of installed apps is accessible to every app having the permission
GET_TASKS
(about 10% of all apps). The combination of installed apps (and their resp. versions) can identify a device pretty well. Add another „raw identifier“, and it might get close to being unique.
By which permission can I tell that an app has access to a given identifier?
Though this was already mentioned in above list, here´s a short sum-up:
- Device_ID/Serial/Build Fingerprint: NONE
- IMEI/IMSI/phone number/connected and visible mobile networks:
READ_PHONE_STATE
- MAC:
READ_NETWORK_STATE
,READ_PHONE_STATE
resp.BLUETOOTH
- Android_ID: for this I couldn´t find any indication; maybe
READ_SECURE_SETTINGS
? - GSF Android_ID:
READ_GSERVICES
- GAID:
INTERNET
- Hostname:
ACCESS_NETWORK_STATE
? - IP addresses, available networks (incl. visible WiFis):
ACCESS_NETWORK_STATE
resp.ACCESS_WIFI_STATE
- Neighboring mobile cell towers:
READ_PHONE_STATE
- Accounts:
GET_ACCOUNTS
- Owner Info:
READ_PROFILE
- installed apps:
GET_TASKS
Possible protective measures
How can we protect identifiers against abusive access?
Without root
… possibilities are, as usual, quite limited. The most obvious step is to check the permissions of an app – best before installing it. Google Play Store (and especially the corresponding app) make that a hard job: both are very much hiding details on this. Easier (and more complete) this can be achieved by e.g. visiting the app´s page at AppBrain – or, if included, check the app lists on this site and click the app´s name. Do those raise an eyebrow, better keep your fingers off that app. Or at least consult the comments and your favorite forum before installing if you´re unsure whether those permissions are legit.
What – too late? You´ve already installed it? Well, those you can check on-device, e.g. using one of the available Permission Checkers. They might even tell you about „suspicious/dangerous combinations“. After the check, you might be tempted to de-install the one or the other app, and replace it by a more decent alternative (again, the app lists here might help you finding such). When in doubt, there´re again the comments, and the forums to ask.
As a minor prevention, you can also head to your device´s „developer settings“ and change the hostname to something more generic (e.g. localhost
). Within limits, you can retract permissions from apps: on Android 4.3 to 5.x using an AppOps FrontEnd, and on Android 6+ using the on-board permission front-end. But that´s rather cosmetical, as security expert Mike Kuketz concludes:4 it´s much too coarse-grained, and some essential permissions are not even listed.
Sometimes it can help to contact the corresponding developer – who often isn´t even aware how intrusive an included advertisement or analytics module is.5 So getting to know, he might be willing to replace it by something „lighter“ and more privacy-friendly.
With root
… much more is possible:
- with XPrivacy it is possible to provide too-curious apps with Fake-IDs instead of the real ones. The very same app can be used to revoke permissions from apps – very fine-grained, if you wish.6
- The Device Serial can be changed via Shell access:
echo -n {neues Serial} > /sys/class/android_usb/android0/iSerial
does that until the device is booted again. To make it persist, integrate the call with the device´s/system/etc/install-recovery.sh
. - To change the MAC address (ugh, well, not really change but rather „overlay“), a Netzwerk Spoofer can be used.
- The Android-IDs could be directly manipulated via
sqlite
in their resp. databases. But who wants to do that should know pretty well what he´s doing (and be prepared for a restore).
Further readings
- Is there a unique Android device ID?
- What´s the difference between the GSF ID and the Android ID?
- list them per ADB: e.g. with Adebar
- Best Practices for Unique Identifiers
- avoid using SSAID and IMEI
- only use Advertising ID for profiling/ads
- (use self-generated, app specific IDs whenever possible)
- What Are Mobile Device Identifiers?
- The Many Identifiers in Our Pockets
- District court rules a unique device identifier is PII (and what companies do with it)
- Android-Device-ID und IMEI herausfinden: So klappts
- Device Identifiers – Chartboost Help Site (inkl. Formate)
- IMEI vs. MEID what is the difference?
-
For details on ADB, see the article ADB for end-users here at IzzyOnDroid ↩︎
-
According to ArsTechnica, access for „normal apps“ is possible via
ACCESS_FINE_LOCATION
resp.ACCESS_COARSE_LOCATION
. ↩︎ -
Statistics on how many apps request a given permission are based on the 13k+ Apps listed at IzzyOnDroid, as of 8/2016 ↩︎
-
Mike´s Blog is focused on security topics. In his article Das Android Berechtigungsmodell: Ein perfides Konstrukt sheds a lot of light on the Android permission system and its shortcomings. An absolute must-read! If you can´t read it in German, try Google´s translation ↩︎
-
For example, Flurry Analytics is quite intrusive, see App Analytics Raises Privacy Concerns ↩︎
-
On Xprivacy and the XPosed Framework, also see the article Xposed: The mighty Android toolbox here at IzzyOnDroid ↩︎