Archive for the ‘WordPress’ Category

As pointed out on the WordPress development blog, a cracker gained access to the wordpress.org servers and replaced the 2.1.1 download with a modified exploitable version. The exploitable download may have been on the site for three or four days!

It may be a good idea for the WordPress developers to sign their releases with a well known and trusted PGP key. This would allow people to verify that downloaded files are really what they should be!
This is a well-established practice used by other projects, for example by the Linux kernel.

The situation has not changed much since WordPress 1.5: WordPress 2.0 still does not support HTTPS access to the admin area when the rest of the blog is served via normal HTTP and I still do not like logging in to my server over unencrypted connections, especially not when using public WLANs. Getting around this WordPress limitation requires quite a few steps:

The Goal

All communication involving passwords or authentication cookies should be done over HTTPS connections. wp-login.php and the wp-admin directory should only be accessible over HTTPS.
Normal reading access, as well as comments, tracebacks, and pingbacks still should go over ordinary HTTP.

The Plan

Add an HTTPS virtual host that forwards requests to the HTTP virtual host

Modify WordPress to send secure authentication cookies, so cookies never get sent over insecure connections accidentally

Require a valid certificate on HTTPS clients. That means to log in to WordPress you need both a valid certificate and a valid password. If someone manages to get your password, he still can not login because he does not have a valid certificate.

The Implementation

Note: This documentation assumes a Debian sarge installation with Apache 2. Some things, in particular Apache module related ones, will be different on other systems.
The server used throughout the instructions is example.org/192.0.34.166. The server’s DocumentRoot is /blog and WordPress resides in /blog/wp. The value of WordPress’ home option is ‘http://example.org’ and the value of its site_url option is ‘http://example.org/wp’.

Prepare the SSL certificates:

Generate your own certificate authority (CA) if you don’t have one already (I’m using the makefile from OpenSSL Certificate Authority Setup for managing mine) and import it into your browser.

Generate a certificate for the SSL server and certify it with your private CA.

Generate a certificate for your browser and certify it with your private CA. Most browsers expect a PKCS#12 file, so generate one with

Make WordPress SSL-ready:
Apply this patch to the WordPress code. It makes the following changes:

Use secure authentication cookies in wp_setcookie()

Make check_admin_referer() work with HTTPS URLs

Use HTTPS URLs for notification mails

Use HTTPS URLS for redirects to wp-login.php

Only allow XML-RPC logins from the local host (ie. the HTTPS proxy)

Add the Mark-as-Spam feature from trunk

The patch is against svn version 3825 of WordPress (ie. WordPress 2.0.3), when you apply it to a newer version, you will likely get some harmless ‘Hunk succeeded’ message. If you are getting ‘Hunk FAILED’ message, just send me note and I’ll update the patch.

Enable the necessary Apache modules:

Install mod_proxy_html. It will be used to replace absolute ‘http://example.org’ HTTP URLs in the WordPress output with ‘https://example.org’ HTTPS URLs:

$ aptitude install libapache2-mod-proxy-html

The module gets enabled automatically after installation.

Enable mod_proxy and mod_ssl

$ a2enmod proxy
$ a2enmod ssl

Debian provides sane default configurations for both modules. You might want to take a look at the configuration files (ssl.conf and proxy.conf) nevertheless.
I have changed SSLCipherSuite to

Modify the blog virtual host to limit access to wp-login.php and wp-admin to the local host. Also completely deny access to files which should never be accessed directly. Here is an example: 10-wp2-example.org

Now setup the HTTPS virtual server: 20-wp2-example.org-ssl
If you are compressing WordPress output you have to enable the RequestHeader line.

Stefan Esser reports that there are two WordPress 1.5.2 versions. The first one, which didn’t fix the problem it was supposed to fix, was available for download for several hours before it silently was replaced by the fixed second version.

It’s hard to understand why the version number wasn’t bumped for the second release and why the WordPress developers didn’t inform users about the mistake.

The comments from the WordPress crowd are a bit weak in my opinion. If there’s FUD about WordPress’ security it’s the sole fault of the WordPress developers!

Some people seem to misunderstand what I said about the latest WordPress update.

I, myself, am perfectly able to figure out what was broken and how it was fixed. That’s not the point. I was commenting on the handling of security announcements by the WordPress developers.

I expect to get information about security issues from a central, easy-findable place from any project or product that has public exposure and more than a handful of users. (Yes, I expect that from open source projects too. Look around the net to see how good others handle it.)
Expecting your users to gather information about a problem from forums, blogs, foreign sites, or the source code is simply unprofessional.

The often used argument that more specific information only helps hackers is just plain naïve: WordPress is open source, its code and even nicely formatted svn changesets are freely available on the web. Hackers are not stupid, they’ll find the issues.

Note, I’m not saying you should post sample exploits publicly. Just give enough information that administrators can determine whether their systems are vulnerable and how severe the problem is. Again, go around the net and look how other projects handle security announcements.