|Locking down WordPress|
If you're going to run it, be aware of the security considerations
WordPress is a leading blog tool, but also has a lot of features that make it interesting to webmasters with communities. It can be considered a general-purpose content management tool as well. This tool has a lot to offer for the serious webmaster--its collection of features can really accelerate the process of putting up a well-done site.
As with any featureful tool, the power and flexibility carry a price in terms of complexity. The security-minded would say that WordPress has a "large attack surface." Let's run down the ways that WP can bite you, and discuss how to avoid some of the gotchas.
My partial list of considerations follows, to kick off the discussion:
issue: general security vulnerabilities. WordPress is so widely used that it gets studied extensively and occasionally effective attacks circulate.
mitigation: Stay current. Running an older WP can be dangerous. Most templates clearly call out the version you are running, so you're not only a target, but easy to find as well. Removing any version tells from your templates is a good idea as well. Subscribe to the release notification mailing list at:
issue: Comment spam. Anonymous or semi-anonymous users can add content to your pages if you allow comments. wp-comments-post.php file from your installation. This assumes you don't need the comment features at all.
mitigation: WP has several built-in features around comment spam, and more functionality is available via plugins. Plugins offer additional functionality that complements or extends the basic spam protections in WP. You should seriously consider running the latest WP version, because the spam mitigation facilities are undergoing constant improvement. The built in features are well-explained in the WP Codex here:
And plugins are listed here:
If you are using WP as a generic CMS, consider disabling comments entirely. There is a configuration setting in WP to do this, but it will not retroactively affect existing posts. You must individually disable comments for these posts. Removing the comment form alone does not stop comment submissions, which are frequently accomplished though scripting.
for the truly paranoid: Alternatively, you can remove or rename the
issue: Trackback and pingback spam. Anonymous or semi-anonymous users can add content to your pages if you allow trackbacks. Trackbacks can be thought of as comments that are automated by design. They are submitted by a special URL that submitted to your server. Normally this is from another blog tool, and occurs when another blogger refers to one of your entries. But it can (and likely will) be subverted for spam purposes also. Allow link notifications from other Weblogs (pingbacks and trackbacks.) This can also be accomplished at the per-entry level by unchecking allow pings.
mitigation: Disable trackbacks and pingbacks. Under Options > Discussion, uncheck
for the truly paranoid: Alternatively, you can remove or rename the wp-trackback.php file from your installation. This assumes you don't need the trackback features at all.
issue: XML-RPC vulnerabilities. WP supports XML-RPC [xmlrpc.com] out-of-the-box. It implements three APIs for posting. This allows submission of posts from alternative blogging clients. Since this interface is made for automation, it may not even be apparent to a WP site owner. Historically, there have occasionally been vulnerabilities in this implementation (WP 22.214.171.124 was released to address a vulnerability). xmlrpc.php.
mitigation: This should really not be enabled by default. If you only submit posts through the web UI, you should remove or rename
for the truly paranoid: write a trap around this file. (details left as an exercise for the paranoid reader)
issue: self-registration of user accounts. WP supports the ability for users to create their own accounts on your system for purposes of posting entries. You probably don't want that. Anyone can register.
mitigation: Under Options > General > Membership, uncheck
for the truly paranoid: remove or rename wp-register.php once your necessary accounts are set up.
That should get the discussion started, I welcome your additional suggestions on running WordPress securely.
Great info, linear, thanks.
It seems like WordPress is a microcosm of all of Web 2.0 - the more power you give to your visitors to contribute to your site, the more potential attack paths you allow.
LOL well thank you for this thread, this is just great info! :-)
Any comments on file permissions? Wordpress lets you edit themes and page code from the admin control panel. This is really handy - I've tweaked the appearance, changed Adsense code, etc., with no need for FTP access. But, it seems to require fairly loose write permission for those files. One comment I saw suggested that the user change permissions back to a more restricted setting after editing, but that kind of defeats the purpose of being able to edit from the browser.
I've had some WP installations hacked by index file replacement, but that seemed to be a server-side attack. In one case, I had locked down the write permissions and it still got hacked again. (I took my sites off that server and moved them to a completely different host.)
As loose as possible, i.e. world-writeable. There is one exception though.*
|fairly loose write permission |
To back up a step, this is a convenience feature--you get a fairly primitive through-the-web text editor in the WP admin screens for any files that you have set permissions appropriately (world-writeable in general). WP uses templates that are .php files in your filesystem, beneath the root of the WP install in a directory called wp-content/themes/<themename>.
I'll leave the discussion on the wisdom of directly editing your production template files for another thread.
The first threat here is that someone overwrites a template file. AdSense publishers have a bit more exposure compared to the rest of webmasters--their AdSense accounts can be yanked. There are also other subtle attacks that don't involve defacements (let your imagination run wild--picture arbitrary PHP code inserted into frequently running scripts on your site).
From a pure security perspective, world-writeable files are bad, and especially ones beneath the document root (since they can be viewed, or invoked if executable). But how bad is this threat really? At this point we sort of blur into a discussion about security of PHP and of shared hosts. But let's look at a few commonly encountered configurations in shared hosting environments, and the implications.
PHP can be configured to run in safe mode [us3.php.net]. This is a Good Thing, as it will make it a bit more difficult for other users that share your host to stomp around in your filesystem. The explanation in the manual is really great, so permit me to quote:
|When safe_mode is on, PHP checks to see if the owner of the current script matches the owner of the file to be operated on by a file function or its directory. |
Nice. But as noted at the top of the safe mode page in the PHP manual, this doesn't really solve every problem with shared hosting--the creative miscreants can find ways around the restrictions. It's just less trivial. So it will stop lamers from looking around your filesystem and making changes, if it is configured with sufficiently restrictive settings. How to tell if safe mode is on? Write a script that invokes phpinfo(), and look for the safe_mode* settings in the PHP Core section of the output.
Safe mode can also be off (seems apalling, doesn't it?), in which case leaving any files world-writeable is a terrible idea. I'll refrain from explaining why in detail, but people sharing your host can write your files, via script. One workable strategy for mitigating this (aside from shopping for a more security-conscious host) is to do all development (template edits, trying new plugins, other hackery) on a throwaway instance of WP. This should use a different database, and ideally should be under a different document root. Then have a process for committing the changes to your production server. Make file permissions as restrictive as possible in production.
WP keeps your content in the database, even though the templates are in the filesystem. Generally this is good. But what are the permissions on your database? It turns out that if you have the appropriate password, it's effectively writable. What's the "appropriate password?" The one in your wp-config.php. Yeah, that world-readable file under the document root. If someone on your shared host has this password, they have write access to your database, hence to your content.
Normally hosts will do a decent (not exhaustive) job of keeping others from browsing your portion of the filesystem. This really should include having safe mode on. If you can get a clue to the existance of a file on your host, you can write a PHP script that opens it (absent safe mode restrictions). This is why informative error messages are bad on your production server.
I feel like I've wandered a fair distance from the topic, but here's the quick summary:
+ Running WP (any script) in a shared hosting environment is not entirely secure
+ PHP's safe mode helps, but isn't perfect
+ filesystem permissions may expose your templates
+ WP has a feature that only works if you set your filesystem permissions to something dumb (forunately permissions aren't dumb by default)
+ database access retrictions may expose your content
+ WP has a world-readable config file
+ none of these threats open avenues for remote exploits (probably the key takeaway here--only your hosting neighbors can bite you)
+ do your template tweaking in a dev environment, especially if you're an adsense publisher
* The exception is if your host runs PHP under your user ID [suphp.org], which is quite uncommon.
|I've had some WP installations hacked by index file replacement, but that seemed to be a server-side attack. |
I've seen similar--every index.php on the box gets replaced and defaced. Offboarding your regular backups is your best defense here. Don't count on your host to be able to roll back your files.
Recovering from this was no big deal, since the database was intact, but it was still frustrating after the host was unable to prevent multiple occurrences.
While you are locking down WP, don't forget about backing up. You'll need your database backup (probably from phpmyadmin), your template and program files (don't forget that some of these are editable online so your saved local copies may not be current), and any other files, e.g., images, that have been uploaded.
Is WordPress only PHP Only or can you get a ASP version?
|WP has a world-readable config file |
I imagine this is to allow you to log in and post from any computer. But isn't this a bit of a security risk? Or is it common among all the top blog systems?
One more question: how does WP compare to ExpressionEngine? I have found that very time-consuming to set up, but certainly powerful. One thing that differs is that you can run multiple blogs with it (from the same database).
Wordpress is all PHP
|+ do your template tweaking in a dev environment, especially if you're an adsense publisher |
Any recommendations for a dev environment?
BTW, this is precisely why I run our forums and blogs on a separate domain and host. At least if things do get hacked, it's just the blog or forum instead of the whole site!
Nothing fancy, just a separate instance of WP where you can try changes out of public view. You'll want to disable the ping features though, which leads me to another feature discussion:
issue: WP pings pingomatic for each new entry by default. This feature exists to alert various RSS aggregators to the presence of a new post on your blog, so they can fetch a feed. Until things are settled, you probably don't want this, and in any case, you probably don't want to expose your dev environment to the feed aggregators. (I have feed aggregators trying to fetch URLs that are long gone because I failed to notice this.)
mitigation: This is pretty easy, just remove the pingomatic URL from the Options > Writing > Update Services section in the admin screens. More detail about this feature is here: [codex.wordpress.org...]
Once things are up and running, you can put this back to get some exposure for your content. This is a nice feature of using WP, but if you don't realize it's on by default, you may inadvertently alert the world to the presence of work that's in-progress.
One of the things that I did was change my template so that it does not have any default text that can be searched for. I have never had a spam problem on my blog. I installed wordpress on a site that was in DMOZ for a friend and within a day or two they had hundreds of spam comments. There are people out there that are spidering the web looking for wordpress installs. One thing you could do is change the default names of all the files. I would not do this unless you really understand php. The funny thing is blog spam is only done by very armature SEO's. The pros have moved on. People are just buying these scripts and pushing a button because they heard it helps. The truly great black hat SEO techniques are never public. If they make it to the forums it means they don't work any more.
Running PHP in safe mode is not the best solution for the shared hosting issue. In fact, safe mode will be completely removed from PHP starting in version 6.
Most hosts do not run PHP in safe mode because it disables various important features (in turn breaking many PHP scripts) including dynamic extensions and backticks. Additionally because of the way the UID system works a vast number of php scripts that don't use any of the disabled functions will still break in safe mode.
Just a friendly reality check so people don't go switching hosts because theirs isn't running safe mode.
Another clarification... 777 (world everything) permissions on data files does not pose a security issue in and of itself. It is necessary for the operation of most PHP scripts to have some files set to these permissions and that's perfectly ok.
By no means do I consider filesystem permissions a major concern for WP users. For the following reasons:
a) they aren't set writeable by default (so presumably if you set them writeable, you at least know they are writeable),
b) they affect templates rather than content since content is stored in tables (plus the .htaccess file for permalinks),
c) hosts do generally do a decent job of keeping other local users out of your filesystem, and
d) there's not a remotely exploitable issue with these files being writeable in general.
The bigger risk if you use the WP template editor features is that you mess up your templates yourself.
Thanks for info