Facebook has taken plenty of criticism for privacy problems over the years, and it’s invested plenty of resources in responding. One specific problem early on was that third party apps could combine their data to create deeper user profiles for tracking and analysis. If one app couldn’t get permission to see a Facebook user’s friends, for example, it might quietly partner with another app that did instead of trying harder to get official permission.
Facebook fixed this in their v2.0 API by giving each app its own set of app-scoped user ids. For example, originally Farmville and Blendr got the same user id for me – 212038 – but in the v2.0 API, they each got their own unique user id. This prevented them from joining their user databases easily.
recently came up with a loophole.
“evergreen” URLs that return a user’s profile picture:
https://www.facebook.com/profile.php?id=[ID]. These work with app-scoped ids
as well as usernames and global ids. Interestingly, for a given user, they
redirect to the exact same final image URL, regardless of the id you use.
As an example, here are two app-scoped user ids for
Snoøpy Barrett, my
trusty cat and test Facebook user: 1507374646254108 and 1449928198665420. If you
HEAD the profile picture URLs for those two ids:
…they both redirect to the same final URL:
This gives you a globally unique identifier for Facebook users that you can use to join two user databases with app-scoped ids, at the cost of one small HTTP request per user.
Facebook could easily fix this by serving profile pictures from a different URL for each app-scoped id. Apps could respond by fetching the pictures themselves, hashing them, and joining on that hash. The cost would still be linear in the size of the two user bases.
Facebook could continue by watermarking images differently for each app. Apps could respond by downsampling the image contents, reducing color palette, running edge detection or other similar algorithms, and hashing the resulting simplified images. I’m sure Facebook could make its watermarks invasive enough that apps would have to downsample so far they’d start seeing collisions, but those watermarks would be pretty ugly. I bet apps would win that arms race.
I reported this to Facebook, and they quickly responded:
This is intentional behavior in our product. We do not consider it a security vulnerability, but we do have controls in place to monitor and mitigate abuse.
…which probably means they rate limit profile picture requests by app id, IP, access token, etc. When they see an app fetch too many profile pictures, they may start to slow down or even reject those requests entirely. That’s totally reasonable. It prevents abuse on any meaningful scale, and it avoids the arms race entirely.
Still, interesting thought experiment!