Mediawiki/Anonymous IP Hash

Note: Thanks to the GDPR, there are efforts to try and get this feature working again.
Warning: Unfortunately, Mediawiki 1.27 has completely overhauled how IP addresses are used and they are probably used to verify sessions. Thus, using this mod will cause actual user account sessions to fail to authenticate. While deeper mods may be possible to make this work, we have given up on it and are seeking ways to hide IPs from user view instead: that allows us to still ban IP ranges anyway.

By default, MediaWiki displays IP Addresses of an anonymous editor in edit history. This obviously has a chilling effect on anonymous user participation.

However, this wiki hashes these IP addresses using a salted bcrypt function, and displays the first 8 characters as an anonymous ID (e.g. ID:D9erK127). The IDs change daily.

These are inspired by 2channel's anonymous ID hashes, as seen periodically on 4chan's /b/.

Activating Anonymous IP Hash

Here's the gist of my anon ID hack to MediaWiki. I can't really package it as an extension or anything because it involves hacking things that apparently aren't supposed to be hacked, but it's not hard to do. - Halcy

1. Add the following to your LocalSettings.php:

// you can leave anon talk pages on, but you'll
// likely end up with useless crud after IDs expire
$wgDisableAnonTalk = true;
function AnonUsername($IP) {
    $options = [
        'cost' => 12, // bcrypt computation cost is 12 instead of default 10
        'salt' => 'PUT RANDOM SALT HERE', // bcrypt requires 22 chars max. change the salt monthly if possible. Static salts are needed for IDs to stay the same within a day or week. Note this may be deprecated by PHP 7.0...

    // Expiry time for hashes: dmY = new ID per day, WY = per week.
    $key = $IP.'PUT RANDOM PADDING HERE'.gmdate('dmY'); // The RANDOM PADDING should be 49 characters (72 - 16 - 8), since for bcrypt, the key string can only be 72 characters
    return 'ID:'.substr(password_hash($key, PASSWORD_BCRYPT, $options), 'id'), 8, 8); // uses bcrypt level 10

The ID is a truncated hash, which, although it increases the risk of collisions, that may be a benefit rather than a liability when it comes to IPs.

Note: Obviously, change the "PUT RANDOM SALT HERE" and "PUT RANDOM PADDING HERE" to some 49 characters of random text: this reduces the risk of brute force attacks. Just bang on the keyboard for a bit, or if you want to be truly random, get an RNG or just roll some dice. The max size of a bcrypt salt is 22 characters. The padding size limit is 49 characters, since the max size of a string for bcrypt is 72 characters.
Warning: Static salts are a necessary evil here since we need to ensure that IDs stay with a user for a day/week. We mitigate this risk by changing the salt monthly. Obviously in passwords, always use random salts.
Warning: While it is certainly miles better than bare IP addresses, hashing is not an absolutely safe way to protect IPs. We use bcrypt and a good salt, so it can stop attackers for quite a long time: but not forever. Maybe 5-10 years or so.

2. In includes/user/User.php, (Mediawiki 1.27.1: getName() Line 2109) find the line that says:

   $this->mName = IP::sanitizeIP( $this->getRequest()->getIP() );

and change it to:

   $this->mName = AnonUsername( $this->getRequest()->getIP() );

3. In includes/user/User.php, (Mediawiki 1.27.1: getBlockedStatus() Line 1600) find the line that says:

   : IP::sanitizeIP( $wgUser->getRequest()->getIP() );

and change it to:

   : AnonUsername( $this->getRequest()->getIP() );

You will need to repeat this mod whenever you update MediaWiki, since obviously an update replaces the system files. And of course the lines may vary, but have generally been similar.

aa tags

On a slightly related note, I hacked an extension together for <aa> tags.

  • Music:DQN-kun / >>6 is not a panda