WordPress security thoughts

In the last few days, there’s been a lot of talk on the Internet about the security of WordPress blog software.

Several shared hosting companies apparently allow customers to view the text of other customer’s files by default, and that allows malicious customers to discover the database password of another site (from the “wp-config.php” file) and alter the site.

Some security researchers think this is a WordPress flaw, but we agree with the WordPress folks that that’s nonsense. The real problem is that these hosting companies are allowing customers to view each other’s files, which shows a reckless disregard for security.

For the record, this kind of attack is impossible on our servers. We prevent customers from viewing each other’s files. In particular, we use suEXEC to run each user’s scripts under a separate Unix user ID, and we ensure that your files are protected from other users at the file system level.

In fact, we go a step further than even most reasonably secure companies: we protect your files even if you change every possible file and directory to be world-writable (mode 777), using an additional layer of Linux “access control list” rules on your top-level directories. We also automatically reset the bad directory permissions for you, just to be sure there are always two levels of protection.

So you don’t need to worry about this kind of attack; “we’ve got your back”.

A different attack on wp-config.php

Separately and coincidentally, our security systems detected a different type of attack on a “wp-config.php” file today. Some “hackers” on the Internet are trying to load files named “wp-config.php~” with a tilde character at the end. In most cases, that file won’t exist, but if you’ve edited your “wp-config.php” file with some text editors, it creates a “wp-config.php~” version as a backup copy.

This is an interesting attack. Of course, it’s not possible to load this file in a Web browser and see the source:

http://example.com/wp-config.php

However, it is possible to see the source of this file if it exists:

http://example.com/wp-config.php~

That’s because the server doesn’t recognize that the “.php~” file contains PHP code, so it shows the visitor the contents (source) of the file, with disastrous results because it contains passwords.

We’ve fixed this potential attack by blocking all requests for filenames ending in “.php~” on our servers, since it appears that nobody is using this legitimately.

If you run your own Web servers, this simple mod_security rule will do the trick:

SecRule REQUEST_FILENAME "\.php~$" "msg:'PHP file backup exploit',deny,status:412,auditlog"

(Just so it’s clear, we’ve already done this for our customers; that rule is mentioned in the hope that it might be useful to someone else. We also mentioned this issue on the WordPress support forums.)

5 Comments

  1. Would RedirectMatch 403 \~ also be an option?

  2. Yes, interestingly you can use RedirectMatch with a 403 status code. RedirectMatch works like Redirect, which allows any status code (“Other status codes can be returned by giving the numeric status code as the value of status…”).

    This syntax worked in our test:

    RedirectMatch 403 ~$

    So as usual with Apache, there’s several different ways of doing the same thing, just to make things more interesting.

  3. It is amazing to me that people want to make all these hacks the fault of the WordPress developers. They seem to forget that any hosting company that doesn’t take precautions to lock down their shared hosting features to where people can’t see everyone’s information are the ones who are really to blame.

    WordPress is a software platform that is continually updating to help prevent hacking, but ultimately it is the responsibility of the website owners to make sure that they are doing what they can to protect their sites by locking down their website and making sure that they host with a reputible company.

  4. This is awesome.

  5. Great post! Been reading a lot about my business’s security. Thanks for the info here!