Every iPhone, iPad and iPod touch has an associated Unique Device Identifier (UDID). You can think of the UDID as a serial number burned into the device - one that can't be removed or changed1. This number is exposed to app developers through an API, without requiring the device owner's permission or knowledge.
Few Apple users realise just how widely their UDIDs are used. Research shows that 68% of apps silently send UDIDs to servers on the Internet. This is often accompanied by information on how, when and where the device is used. The most common destination for traffic containing a user's UDID is Apple itself, followed by the Flurry mobile analytics network and OpenFeint, a mobile social gaming company. These companies are uber-aggregators of UDID-linked user information, because so many apps use their APIs. Trailing behind the big three are thousands of individual developer sites, ad servers and smaller analytics firms. Users have no way to stop their device from offering up their UDID, telling who their data is being sent to, or even telling that it's happening at all. This situation has caused wide-spread concern, including coverage in the Wall Street Journal, and two lawsuits aimed at Apple.
The saving grace is that your device UDID is not linked to your real-world identity. If it were possible to de-anonymize UDIDs, the result would be a serious privacy breach. Apple is well aware of this, and explicitly tells developers that they are not permitted to publicly link a UDID to a user account.
I recently published a tool called mitmproxy, a man-in-the-middle proxy that allows one to intercept and monitor SSL-encrypted HTTP traffic. Using mitmproxy to view the encrypted traffic sent by my own iOS devices, I was able to observe protocols and data flows that have clearly received very little external review. A slew of interesting security results followed (keep an eye on this blog), but by far the most alarming was the fact that it was possible to use OpenFeint to completely de-anonymize a large proportion of UDIDs.
De-anonymizing UDIDs with OpenFeint
Linking UDIDs to OpenFeint user accounts
When an OpenFeint-enabled app is first fired up, it submits the device's UDID to OpenFeint's servers, which then return a list of associated accounts:
https://api.openfeint.com/users/for_device.xml?udid=XXX
This is a completely unauthenticated call - you can try it out by cutting and pasting it into your browser, replacing XXX with your own UDID. Here's an example of the response for my UDID, with sensitive information removed:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<user>
<chat_enabled>true</chat_enabled>
<gamer_score>XXX</gamer_score>
<id>XXX</id>
<last_played_game_id>187402</last_played_game_id>
<last_played_game_name>tiny wings</last_played_game_name>
<lat>XXX</lat>
<lng>XXX</lng>
<online>false</online>
<profile_picture_source>FbconnectCredential</profile_picture_source>
<profile_picture_updated_at>XXX</profile_picture_updated_at>
<profile_picture_url>http://XXX>
<uploaded_profile_picture_content_type nil="true">
</uploaded_profile_picture_content_type>
<uploaded_profile_picture_file_name nil="true">
</uploaded_profile_picture_file_name>
<uploaded_profile_picture_file_size nil="true">
</uploaded_profile_picture_file_size>
<uploaded_profile_picture_updated_at nil="true">
</uploaded_profile_picture_updated_at>
<name>XXX</name>
</user>
</resources>
Included is my latitude and longitude, the last game I played, my chosen account name, and my Facebook profile picture URL.
Linking UDIDs to GPS co-ordinates
If the user has opted to allow OpenFeint to use their location, latitude and longitude is returned in the profile results. This lets us trivially associate a UDID with GPS co-ordinates.
The location leak was fixed by OpenFeint after my report. Although some portions of the OpenFeint API still returns a user location, it seems that it is no longer served for direct profile requests.
Linking UDIDs to Facebook profiles
If the user registered a Facebook account with OpenFeint, a profile picture URL hosted by the Facebook CDN was returned in the user's profile data. Facebook profile picture URLs include the user's Facebook ID, directly linking it to their Facebook account.
For example, here's Bruce Schneier's Facebook profile picture URL:
http://profile.ak.fbcdn.net/hprofile-ak-snc4/41795_60615378024_8092_n.jpg
The 11-digit number in this URL is his Facebook user ID. We can now view his profile using a URL like this:
http://www.facebook.com/profile.php?id=60615378024
This final step represents a complete de-anonymization of the UDID, directly linking the supposedly anonymous identifier with a user's real-world identity.
The Facebook ID leak was fixed by OpenFeint after my report.
OpenFeint's response
I reported this problem to OpenFeint on 5th of April. I did not hear back from them immediately, but I knew they were working on the problem because their API stopped returning GPS coordinates and Facebook profile picture URLs. On the 12th, I received an email from Jason Citron, OpenFeint's CEO, who wanted to set up a phone conversation with me, him and an OpenFeint legal representative. We spoke on the evening of the 20th of April. I recapped my findings and expressed concern that their API still linked UDIDs to user accounts. They thanked me for the vulnerability report, confirmed that they had tightened their API in response to it, and asked for more time to consider the issue before I released anything. The following morning, it was announced that OpenFeint had been bought by GREE for $104 million.
Last week I received what I assume is OpenFeint's last word on the matter, in the form of an email from Jason Citron: "We will continue to pay attention to the issues you raised and will continue to adjust our practices as necessary." At the time of writing, OpenFeint's API still allows you to associate a UDID with a private user information.
Impact
Testing with a small corpus of UDIDs gathered from my own and friends' devices, I was able to link roughly 30% of UDIDs to GPS co-ordinates, 20% of users to a weak identity (e.g. OpenFeint profile picture, user-chosen account name), and 10% of UDIDs directly to a Facebook profile. I stress that my sample was small and probably unrepresentative - only OpenFeint knows what the real numbers are. None the less, we can make a broad guess at the magnitude of the problem, based on the fact that OpenFeint claims to have 75 million users:
- This would mean that about 7.5 million users may have had Facebook accounts linked publicly to their UDIDs until OpenFeint stopped returning profile picture URLs a few weeks ago.
- About 22.5 million users may have had GPS co-ordinates linked publicly to their UDIDs until the issue was corrected.
- About 15 million users may still have identifying information like profile pictures and user-chosen account names (that can often be used to identify users) exposed.
- All 75 million users still have personal details like the last OpenFeint-enabled game they played and whether they are online (i.e. logged in to the OpenFeint network) exposed.
Although the Facebook and GPS de-anonymization issues have been repaired, we have to consider the possibility that these vulnerabilities have already been used to de-anonymize a database of UDIDs.
Conclusion
I want to stress that the problem here is not primarily with OpenFeint. By designing an API to expose UDIDs and encouraging developers to use it, Apple has ensured that there are literally thousands of databases linking UDIDs to sensitive user information on the net. A leak from any one of these - or worse a large-scale de-anonymization like the OpenFeint one - inevitably has serious consequences for user privacy.
I should note that this is not quite accurate. The UDID is actually a computed value - a hash calculated over a set of identifying hardware attributes. In a sense, it only really exists as an API call.