author image
On The Recent WordPress Blog Hackings
Apr 12 2010 • Written By Duane Storey • 8 Comments

There’s been a lot of talk on the web today about some recent WordPress blogs that were hacked, so I wanted to chime in a bit. Thankfully nobody I know was affected by this latest attack, but I’ve had friends hit on previous ones.

First, no system is entirely secure. Ultimately you try to do your best to secure a system by adding obfuscation, encryption, obscurity, passwords, etc., but each of those systems has weaknesses as well. Even the public key encryption that forms the basis of SSL is attackable, it just currently relies on a level of computational complexity to make it nearly impossible for the average attacker.

The latest attack involved a user on Network Solutions going around and reading information from the wp-config.php file which contains the basic database information for WordPress itself. Once the user had that information, they effectively had the ability to change all the WordPress related configuration settings and stored content. The following are listed as reasons why this attack was successful, so I thought I would comment on each in order.

  1. The file permissions on wp-config.php weren’t restrictive enough. On Linux machines, you can assign file permissions separately for the owner of a file, for the group the file is in, and for everyone else. This is typically written in octal notation as 644 or 640, where the first digit is the owner’s permission (6 means read and write), the second digit the group (4 means read-only) and the last digit is for everyone else (a zero indicates it’s not readable or writable). A lot of articles I’ve read about this exploit indicate that this attack would not have worked had the permissions not allowed reading of the file by everyone. That’s probably true. Unfortunately it doesn’t take into account the reality how wp-config.php is created, or how the average Linux system sets file permissions. I can’t speak to how wp-config.php is created, but if it doesn’t already do it, WordPress should probably set the permissions on that file to 640 upon installation. In any case though, simply check the permissions of that file after an installation and adjust them accordingly.

    Unfortunately on most of the Linux systems I’ve encountered, the default mask for the files is usually 664, meaning the files are readable by everyone, and writable by the owner and the group. In an ideal world the second parameter would always be a 0 or a 4 as well (or a 5 for executable files), but many hosting providers require web files to be group readable as well, since Apache doesn’t run as the file’s owner. On some sites that use suPHP, the PHP process will actually be run as the owner of each PHP file, which basically means only the owner attribute is really important, and the others could conceivably be set to 0.

  2. The WordPress database password is stored in plain text. This is true, but there’s no real way around it. If the permissions of wp-config.php are set such that wp-config.php can only be read by Apache or the owner of the file, then this part really isn’t that relevant. But some people are arguing that if the password wasn’t stored in plain text this wouldn’t have happened.

    One option is to store the password in an encrypted form using symmetric encryption. As several people pointed out on Twitter, this is sort of useless since it would require storing the encryption key somewhere in plain-text as well, which causes the same problem. Also, the typical symmetric encryption library on PHP is mCrypt I believe, and it’s rarely installed on a host.

    Another option is to store the password in an encrypted form using public/private key encryption. The password could be encrypted using the private key, the private key deleted, and then the public key either stored on disk or in a PHP file. If anyone acquired the public key, they could easily decrypt the password, but it would provide a slight barrier for anyone not familiar with how public key cryptography works. Also, the public key could be stored as 640 or 600 on disk (although this is effectively a non-issue if those permissions were used originally). This type of scheme also relies on OpenSSL being installed, which it often is, but not on 100% of systems.

    I saw one comment on a site saying the password should be stored using MD5 and a salt. Since a hash is not reversible, this wouldn’t do the trick – ultimately MySQL requires an unencrypted password, so one-way transforms aren’t going to help.

If you’re an end-user that has a site hosted somewhere, you should do the following:

  1. Set the file permissions on wp-config.php to be 640. If you have SSH access you can do that by typing “chmod 640 wp-config.php”. If you have an FTP program you can usually do it by adjusting the file properties

If you’re a hosting provider, here are some tips:

  1. Don’t allow other users to browse each other’s directories. The base user directories should not be navigable by end users, only the main owner and potentially the group (depending on how Apache is set up)
  2. Don’t assign users to the same group Apache is in. If you require group permissions for Apache to run, don’t assign other users to that group or they will always have the same rights as Apache
  3. Scan your users’ directories for any wp-config.php files that has everybody permissions as readable and potentially adjust them all
  4. Change the default file mask so that the everyone/world permissions are not readable by default
  5. If your site somehow needs everyone permissions to be readable, then you probably need to re-architect your hosting environment.

If anyone has any other suggestions (or notices any mistakes), drop them in the comments below and I’ll update this post accordingly. Ultimately, every user needs to take responsibility for the security of their own site. While it’s easy to point the blame at WordPress, this type of exploit can occur with any PHP program that makes use of a database when it’s configuration files are exposed to all users on a system.

8 Comments

  1. Jeff Mackey

    http://SIX15.com

    April 12th, 2010

    Haven’t tried it myself yet, but I recently read that you can move wp-config up one directory essentially removing from view. WordPress is coded to look for it there if it’s not in the web root.

  2. Example

    April 12th, 2010

    Changing the config to 640 broke my WP install. I had to revert to 644 to get it to work.

  3. Duane Storey

    BNC Development Guru

    April 12th, 2010

    Then it sounds like your host requires read access for everyone, which is a bad thing. Which hosting provider are you using?

  4. Example

    April 12th, 2010

    wouldn’t mentioning the host open up my site to a hacking attempt?

  5. Duane Storey

    BNC Development Guru

    April 12th, 2010

    If it’s 644, you’re already potentially open to a hacking attempt. But mentioning it here may persuade others to take a look at theirs on the same host. If it’s a problem lots of people are having, maybe the host can help.

  6. Thanks for this simple and hopefully effective tip. Changed it and my site seems to look ok.

  7. Example

    April 13th, 2010

    Thanks for the article, since my host changed group ownership and my WP install now works with 640 (I assume that the 640 in your previous post was meant to be 644).

  8. Thanks for the tip. I am surprised hosts allow such an obvious exploit.