Skip to content

Instantly share code, notes, and snippets.

@digitalhydra
Created January 19, 2016 15:19
Show Gist options
  • Select an option

  • Save digitalhydra/2c63f95255f945023a43 to your computer and use it in GitHub Desktop.

Select an option

Save digitalhydra/2c63f95255f945023a43 to your computer and use it in GitHub Desktop.
check if avatar/gravatar is valid(exists)
function validate_gravatar($email) {
// From http://codex.wordpress.org/Using_Gravatars
// Craft a potential url and test its headers
$hash = md5($email);
$uri = 'http://www.gravatar.com/avatar/' . $hash . '?d=404';
$headers = @get_headers($uri);
if (!preg_match("|200|", $headers[0])) {
$has_valid_avatar = FALSE;
} else {
$has_valid_avatar = TRUE;
}
return $has_valid_avatar;
}
@mrhoffmann
Copy link

mrhoffmann commented Dec 1, 2022

TLDR; the above solution doesn't work anymore since how gravatar nowadays work

Okay, so i took a look at this since i was fixing an integration and didn't find any easy answer to this.
Looking at it, the request to gravatar, independent of however you do it, doesn't reply anything else but a response code of 200, even if you request from a md5-sum that you know doesn't exist.

Therefor, this above, may have worked at one point, but they perhaps redid it.

You could do this approach, to validate if the image responded is the false positive or not:

function imageData($email){
    $url = 'https://secure.gravatar.com/avatar/'.md5(strtolower(trim($email)));
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);

    $imageData = curl_exec($ch);
    curl_close($ch);
    return $imageData;
}

function imageHash($email){
    $hash = hash('sha256', imageData($email));
    return $hash;
}

function isFalsePositiveGravatarImage($email){
    return strcmp(imageHash($email), "991b89e27049fdb8d2db1c46db95b9809e5f5a7d2afc3377634144cfea680f70");
}

To explain:

  • imageData returns the actual data from the response, this we could directly use to assemble as an image.
  • imageHash converts this data into a sha256-sum, we could might as well use md5 or base64 or even the raw data itself.
  • isFalsePositiveGravatarImage is where we do a string comparison, if 0, they are the same, if not, they aren't, regarding strcmp command, you can take a look at strcmp here.

On that page, there's an excellent explanation right here:

strcmp("5", 5) => 0
strcmp("15", 0xf) => 0
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000) => 0
strcmp(NULL, false) => 0
strcmp(NULL, "") => 0
strcmp(NULL, 0) => -1
strcmp(false, -1) => -2
strcmp("15", NULL) => 2
strcmp(NULL, "foo") => -3
strcmp("foo", NULL) => 3
strcmp("foo", false) => 3
strcmp("foo", 0) => 1
strcmp("foo", 5) => 1
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning

Now, to use this, you can call it in this order:

isFalsePositiveGravatarImage("this_doesnt_exist");

At the point of writing, i'll receive a hash of 991b89e27049fdb8d2db1c46db95b9809e5f5a7d2afc3377634144cfea680f70 and can quickly get the response of 0, since it does exactly match. If I'd call it with my email which has an avatar, I'd not receive 0, since i have one.

@fdciabdul
Copy link

TLDR; the above solution doesn't work anymore since how gravatar nowadays work

Okay, so i took a look at this since i was fixing an integration and didn't find any easy answer to this. Looking at it, the request to gravatar, independent of however you do it, doesn't reply anything else but a response code of 200, even if you request from a md5-sum that you know doesn't exist.

Therefor, this above, may have worked at one point, but they perhaps redid it.

You could do this approach, to validate if the image responded is the false positive or not:

function imageData($email){
    $url = 'https://secure.gravatar.com/avatar/'.md5(strtolower(trim($email)));
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);

    $imageData = curl_exec($ch);
    curl_close($ch);
    return $imageData;
}

function imageHash($email){
    $hash = hash('sha256', imageData($email));
    return $hash;
}

function isFalsePositiveGravatarImage($email){
    return strcmp(imageHash($email), "991b89e27049fdb8d2db1c46db95b9809e5f5a7d2afc3377634144cfea680f70");
}

To explain:

  • imageData returns the actual data from the response, this we could directly use to assemble as an image.
  • imageHash converts this data into a sha256-sum, we could might as well use md5 or base64 or even the raw data itself.
  • isFalsePositiveGravatarImage is where we do a string comparison, if 0, they are the same, if not, they aren't, regarding strcmp command, you can take a look at strcmp here.

On that page, there's an excellent explanation right here:

strcmp("5", 5) => 0
strcmp("15", 0xf) => 0
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000) => 0
strcmp(NULL, false) => 0
strcmp(NULL, "") => 0
strcmp(NULL, 0) => -1
strcmp(false, -1) => -2
strcmp("15", NULL) => 2
strcmp(NULL, "foo") => -3
strcmp("foo", NULL) => 3
strcmp("foo", false) => 3
strcmp("foo", 0) => 1
strcmp("foo", 5) => 1
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning

Now, to use this, you can call it in this order:

isFalsePositiveGravatarImage("this_doesnt_exist");

At the point of writing, i'll receive a hash of 991b89e27049fdb8d2db1c46db95b9809e5f5a7d2afc3377634144cfea680f70 and can quickly get the response of 0, since it does exactly match. If I'd call it with my email which has an avatar, I'd not receive 0, since i have one.

too much .. gravatar has built in parameter d means default to check wether the md5 has user data or not

https://www.gravatar.com/avatar/00000000000000000000000000000000?d=https%3A%2F%2Fexample.com%2Fimages%2Favatar.jpg

@mrhoffmann
Copy link

I appreciate the comment, i did look for it but couldn't find anything about it when I checked! Will look harder next time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment