Developers: Stop Uploading Address Books.
2 min read

Developers: Stop Uploading Address Books.

Users: Don’t be so trusting.

“SomeNewApp would like to access your contacts.”

If you’re like most people, you’ll press “OK” without even blinking an eye. If you’re a developer, then you’re probably a bit more cautious.

Because, after you click “OK”, what happens? Well, that depends.

These days, anyone can throw an app together and publish it to the AppStore. And while Apple has a fairly stringent review process, they can only review what happens on the device, not what happens with the data that leaves the device.

Most of us remember the Path incident. Though, this was a bit more devious in that it never asked for your permission (Apple since fixed this bug).

We upload the address book to our servers in order to help the user find and connect to their friends and family on Path quickly and effeciently as well as to notify them when friends and family join Path. Nothing more. —Dave Morin

Morin’s response is technically accurate, they upload the contact book to connect the user with their friends. Do they store the data? Probably, as they have to in order to match new friends that join the service long after you’ve uploaded your address book. But, even if a service doesn’t store them in a database, there are all sorts of other places it can go, such as into the logs that nearly all services keep for debug and analytical purposes. The data is there and it’s discoverable.

That approach is wrong. You don’t need to upload phone numbers and email addresses, just a representation of them. Most developers believe that sending email addresses and phone numbers over SSL and storing them securely on the server is good enough. It’s not.

The number of services that have contact data for millions of people (journalists, celebrities, politicians, etc) is probably quite staggering. Don’t be that service.

You should only collect email address and phone number if users willingly give it to you. If you need to match them with their friends that sign up later, only collect and store contact details in a way that is matchable, but irrecoverable.

Here’s the right way. Simply one-way obfuscate (e.g., hash, SHA1) any piece of personally identifiable information (email, phone number, etc) for each contact and store that. Use a little salt too. Then, when it comes time to match, do it on the obfuscated keys. At this point, you don’t even need to care if it’s an email address, phone number because it’s just an opaque blob. Disclaimer: This is not meant to prevent against hacking attacks, as hashing (especially phone numbers) is easily defeated.

A fine solution is to do this on the server, but the best solution is to do it on the client before sending up the data. That way, you can make the guarantee to your users that their contact data never leaves their phone.

Also, just because you send data over SSL doesn’t mean you’re in the clear. Savvy people will inspect your traffic with a simple MITM proxy and check out what you’re doing. So instead of seeing this:

“Contacts”: [{
  “Emails”: [“davidbyttow@example.com”], 
  “PhoneNumbers”: [“+15550001234”]
}]

They only see this:

“Contacts”: [{
  “Emails”: [“sTYVRpsNfoluk5nQzoTnhu2AyW0=”], 
  “PhoneNumbers”: [“ga7tSDlB0s45nUKnmn9XERVTBqE=”]
}]

Unfortunately, now you can’t get Kanye West’s phone number because one of his bodyguards signed up for your service. Sorry! :-(


Follow me @davidbyttow.

Special thanks to Dan Pupius for making me realize the importance of this practice.

Enjoying these posts? Subscribe for more