The problem:
Gravatar hashes are somewhat easy to crack. Websites are super easy to scrape. Sites with Gravatar urls in the img-src or profile link make it trivial to generate lists of hashes to crack. Other data available on sites and in Gravatar profiles can be used to generate targeted wordlists which make cracking a large proportion of the hashes much quicker, in seconds rather than days.
The goal:
Make it so that sites don’t have to use Gravatar’s easily cracked hashes on the front end to get data from Gravatar.
How it currently works:
Gravatar works like this. It’s easiest to look at Matt Mullenweg’s profile (JSON, XML) because he has photos on it other than his avatar and I’ll refer to the structure of those urls.
Currently the profile url is https://en.gravatar.com/767fc9c115a1b989744c755db47feb60.json and the avatar image url is https://secure.gravatar.com/avatar/767fc9c115a1b989744c755db47feb60 where 767fc9c115a1b989744c755db47feb60 is the md5 hash of his email address.
If you look at Matt’s other photos, you’ll see they’re at eg
https://secure.gravatar.com/userimage/5/2873000ea367cd46cae55418e4eac32c
and I’m going to call that last hash in his photo url HASH_OF_FILENAME although I’m not exactly sure what it’s a hash of and the user id (5) USER_ID
What if it worked something like this:
My first thoughts are to tweak and add to what’s already there, so what if these existed and sites could use them?
Gravatar avatar url:
secure.gravatar.com/userimage/USER_ID/HASH_OF_FILENAME
Gravatar profile url:
secure.gravatar.com/userprofile/USER_ID/HASH_TO_PREVENT_ENUMERATION
For the new profile url, you’d still use the usual JSON, XML, PHP responses by adding the appropriate extension. (If you wanted the web profile, it would redirect to the usual one with the username eg en.gravatar.com/matt)
The current profile endpoints would still be there for backwards compatibility. This is because I’m assuming it’s difficult to get rid of something someone might be using but much easier to add something new separately.
The new profile would strip out the unnecessary email hashes so the JSON response from secure.gravatar.com/userprofile/5/HASH_TO_PREVENT_ENUMERATION.json would look like this:
Ok but how do the sites know what those urls are?
One way would be to add in two fields like these to the current profile API response eg (apols for the formatting)
{"entry": [
{
...
"anonProfileUrl": "https://secure.gravatar.com/userprofile/USER_ID/HASH_TO_PREVENT_ENUMERATION",
"anonImageUrl": "https://secure.gravatar.com/userimage/USER_ID/HASH_OF_FILENAME"
"prefererredUsername": ...
So let’s say those three things have been added:
- anonUserProfile API(ish) available at eg secure.gravatar.com/userprofile/USER_ID/HASH_TO_PREVENT_ENUMERATION.json
- avatar available at secure.gravatar.com/userimage/USER_ID/HASH_OF_FILENAME
- new field
anonProfileUrl
in current Gravatar profile response - new field
anonImageUrl
in current Gravatar profile response
What is a possible way sites can use this?
Well, first, they start storing the Gravatar urls in usermeta for each user. gravatar_avatar
will be the meta key for the avatar and gravatar_profile
will be the meta key for the profile. gravatar_avatar
is used in place of the generated Gravatar url for avatar img-srcs and gravatar_profile
is used in place of the url for Gravatar profiles. Neither is required.
When someone registers, they get assigned a hash made from whatever, but not their email address, maybe site name and user id and use that to make www.gravatar.com/avatar/HASH. This url is stored in gravatar_avatar
and the image itself is whatever default image the site owner has chosen for users without a Gravatar account. It’s fine to get the avatar this way because the HASH isn’t made from any personally identifiable information.
If they decide they want to use their actual Gravatar avatar (in this fantasy version, Gravatar images and profiles are opt-in rather than opt-out), they can go to their profile and choose that. The site will have helpfully done the legwork and used the anonImageUrl
in the normal API response to populate the image field and, if the user chooses to use it, that url (the one of the form secure.gravatar.com/userimage/USER_ID/HASH_OF_FILENAME) will be used for gravatar_avatar
. Same sort of thing for the profile.
I’m sure, like 100% sure, that there’s something in here that doesn’t make sense. But the way it work for the user does, I’m thinking it’d be similar to Stack Overflow for users. And any issues should be fixable.
Leave a Reply