jacobwb / hashover-next

This branch will be HashOver 2.0
GNU Affero General Public License v3.0
420 stars 87 forks source link

Feature Request: EU GDPR and Gravatar #303

Open myFrank-wk opened 3 years ago

myFrank-wk commented 3 years ago

For privacy reasons I have to use the option "Avatar icon display mode" = "None". Actually, I think the Gravatar option is very nice, but the way the function is implemented in HashOver, I am not allowed to use it in the EU for legal reasons. The GDPR stipulates that a user must be able to object to the use of their personal data. If the avatars are switched on, the email address is compared directly with Gravatar. This is the only way to deliver the personal picture of Gravatar. The email address of a user who does not have a Gravatar account will be transferred to Gravatar without the possibility of objection.

A checkbox "Use Gravatar" in the input form would be nice. The checkbox should be disabled and only when the checkbox is enabled will the email address be compared with Gravatar.

da2x commented 2 years ago

I am not allowed to use it in the EU for legal reasons. […] If the avatars are switched on, the email address is compared directly with Gravatar.

I think both your assertions here are incorrect.

I’m not a lawyer and this isn’t legal advise.

TL;DR: Don’t worry about it; this is really really small fish. You won’t get fined over this given the state of the industry and minimal enforcement. Apply patch 180eb869a1e63fa5d4ee9d346bfb5d0e9c236776 to reduce how much data is sent to Gravatar.

You never transmit the user’s email address to Gravatar. The email goes through a one-way hash. Gravatar can only match that hash up to an email address if they already know the address and can perform the same one-way hash operation for comparison.

The hash is, however, a persistent identifier. The hash is also made public. It could theoretically be used to map your social network, but … not really. Gravatar is used on random websites with comments from random people. There isn’t much value to this data as a set. This could be problematic for users who don’t have an existing customer relation with Gravatar, though. Luckily, we can easily check to see if the user has an account with Gravatar.

Here’s a partial solution: Periodically query Gravatar on the backend and check if the user has an account with the service (test if gravatar.com/avatar/email-hash?d=404 returns 200 or 404). If the user doesn’t have an account, salt the email used for the hash (before hashing the email address, append "some-site-unique-string" to the hash. This hides the hash of the user’s actual email address, and the user still get a consistent hash and image on the site. Alternatively, use a local fallback image. Periodically recheck to see if the email is still registered or not. Only use the real hash if the user has an account with the service.

The second part of this is how much data visitors send to Gravatar. Pull request #311 reduces how much potentially personal data each visitors sends to Gravatar. With this patch, they would get the hash and your IP only.

An alternative (and more complete) solution is to cache the avatar images on the server. It could be performed as part of the periodic checking discussed above. However, it would be pointless — the image itself is unique and hashable. A motivated adversary could use reverse image search to stalk you online just as easy as they could stalk you with the hash. It further reduces how much data is sent to Gravatar, but #311 removes the most objectionable/marketing/interest/personal data from the equation.

jacobwb commented 2 years ago

While this is not implemented as a feature, you can achieve this with the frontend settings.

Here's an example, assume is_gdpr is a boolean that is set true after the user checks a box or otherwise agrees to share their personal data and set cookies, etc. I really should add this to the documentation.

<script type="text/javascript" src="/hashover/loader.php"></script>

<script type="text/javascript">
    var hashover = new HashOver ('hashover', {
        settings: {
            iconMode: is_gdpr ? 'image' : 'count',
            setsCookies: is_gdpr
        }
    });
</script>

If there are other settings that are affected by GDPR, you should be able to adjust them in a similar manner through the frontend settings. Feel free to add to my code example and I will add a note in the documentation about GDPR.

da2x commented 2 years ago

In lieu of the massive Gravatar breach, I’ll implement a local identicon replacement not using email hashes.

da2x commented 2 years ago

I’m done. I’ll open a pull request once #311 is merged. I’ve added it as a new API that accepts a size and hash argument to generate SVGs. The generation is quick, but large installs will want a caching proxy in front. Unlike Gravatar, the icons are immutable, so clients can cache these icons for months instead of minutes. It uses a salted version of the email hash to generate the icons. There’s no information leakage of the user’s email address. The user will only be identifiable on the current installation of Hashover. (That’s the point, after all.)

Here’s some examples:

Examples of Identicon graphics.

I can add square ones too, the ones that imitate 8-bit art. However, that’s a lot more work. It’s very hard to avoid generating bad symbols or symbols people don’t want to be associated with (sad face, crosses, swastikas, genitals, letters, numbers, … ).

theadventuresock commented 2 years ago

@da2x these are so cool. I'd really love to use these icons instead of Gravatar. Ideally, I'd like to let people upload their own, but eh, this could be a nice "default" option to have.