Privilege separation in WordPress


A recent retweet by Jeremiah Grossman got me thinking. Why doesn’t WordPress implement privilege separation in their blog engine? After all it is fairly simple and can be implemented in a few lines of code.

I don’t know the reason to be honest, as this is one of the basic rules of security. Few months ago I did it for my blog, since I don’t see a valid reason why anyone coming across the Internet needs to have “drop table” privilege or similar on my blog’s database. I looked around for a convenient mailing list to post my idea to and unfortunately I couldn’t find one, so I gave up on trying to message the idea directly to WordPress developers, but now I’ve decided to at least post it for people to take advantage of it.

Here is what I have done that should give you basic level of privilege separation with just a simple WordPress tweak.
First, you need to have the two separate database users – admin and public. We also need to assign the proper privileges/permissions (after all this is the main idea):

public -> db: [SELECT,INSERT]

Since I have comments enabled, I had to give the public user the INSERT privilege, but at least I have taken away the 10 extra privs away from it. If you don’t allow comments on the blog, you can even remove the INSERT functionality, though I haven’t tested this one and don’t know if anything else would break.

The only other thing left to do is configure WordPress to pick the right database user. This is accomplished easily through wp-config.php:

if ( defined('WP_ADMIN') || defined('DOING_CRON') )  {
  define('DB_USER', 'admin');
  define('DB_PASSWORD', 'admin_password');
} else {
  define('DB_USER', 'public');
  define('DB_PASSWORD', 'public_password');

I’ve only had this customization interfere once in my almost half year since I’ve implemented it. It was during WordPress upgrade, which required a change to the database schema. In such cases, it is trivial to restore back to the default behavior for the duration of the upgrade and then go back to separate users.

I hope this helps people reduce some of the attack surface on their blogs and ideally WordPress will do this natively in the future.

Tags: , , ,

  • Matt


    I really like this idea and would love to see it in WordPress (I’m a luser myself). My only thoughts around it are if you’re running an older version of WP or have a vulnerable theme, the vector is going to be SQL injection of some kind. While you may stop some or most of the attacks available, you’re still going to leave the server open to the most basic (but no less useful) injection attacks. I’m basing this on stuff I’ve been playing with on Kioptrix (level 3 & 4) and my pondering on it as I write this….

    What do you think ?


    • Nasko

      Security is never a 100% concept, there will always be a way that security can be compromised. As such, it is all about making it harder for the attacker to succeed. I do mention at the end that this change is about reduction of attack surface, not total elimination of attacks. If we all start taking basic steps to make software more secure, eventually, after a lot of mileage, we can probably get to a state where it is much harder to compromise software than it is today.

  • Gennady

    This is quite interesting, thanks for sharing. A couple of thoughts, though, how would the creation of 2 users be streamlined in the core/during installation? Would users have to create two separate users, grant separate privileges manually? Is there are way to automate this without the need for user further user setup? A couple of lines of extra code don’t hurt, but the setup overhead for simple users would turn down most regular users. A way to automate would require much more effort. Thanks again, interesting concept overall.

    • Nasko

      Today WordPress does ask you to create a database and a user, right? There are plenty of instructions on how to achieve that step. Just create alternative where you require two database users and provide the proper steps. If the user can’t follow, they are better off using or some other service that will host it for them. I bet the WordPress team can come up with more clever ways to streamline the setup.