The keys to running a successful WordPress blog — technically speaking

Heise online reports WordPress is going to clean up the plugins dir because plugins “suck” and that — despite this fact — WordPress has become a constant in the web because large blogs such as Smashing Magazine are using it.

How do large WordPress blogs like Smashing Magazine accomplish this when plugins suck so much?

In the past years I have responsible for many WordPress installations, including Smashing Magazine‘s WordPress installations. I think I can tell you the keys that make a blog running WordPress successful or unsuccessful, technically speaking.

It’s the plugins:

  • How many of them are installed – the less the better!
  • Which ones are installed — always look how experienced the plugin’s developer is!
  • How they got chosen — make a security audit, either by yourself if you are competent, or hire someone how is!

In fact there are many, many WordPress plugins out there that have been developed by, let’s say, inexperienced developers. There are *tons* of security issues out there. The more plugins you install, the more security issues you install.

When I take over as a WordPress sysadmin, the first thing I do is throw out all unneeded plugins. Then I update the remaining ones. Then I try to further reduce the amount of plugins, either by implementing features myself or by replacing plugins with more capable/secure ones.

Here’s my last tip: If you cannot find a decent, capable, and secure WordPress plugin that suits your needs, hire a good developer with a security background to create it for you. Obviously you have to make sure not to hire one of the inexperienced developers. Please don’t go collecting plugins like “Oh I take this, and this one as well, this one sounds nice too” — this is not going to work in the long run. A successful WordPress blog is *always* run by competent admins and developers, not by “WordPress plugin collectors”.

Of course there are other factors as well, like always having the most recent versions of them installed, or to have interesting contents, but those are the keys IMHO.

Optimize WP-PostRating db table

Suffering from slow WP-PostRating plugin? Here’s how you could make it faster — add an index to the plugin’s database:

ALTER TABLE wp.wp_ratings ADD INDEX Select1(rating_postid, rating_ip);

Quick and painless. Replace wp.wp_ratings with the table name you are using.

It is BTW quite common for WordPress plugins that come with their own database tables not to create indexes. You may not notice that on a low traffic server but when using such plugins on high traffic servers such as Smashing Magazine you have to look out for them and take action.

WP Plugin Security: Multiple Leaks in WP-PhotoContest

What IS WP PhotoContest? The readme states:

This plugin permits you to create a ‘voting for photos-contest’ from the WordPress admin panel Subscribed users can uploads photos and everyone else can vote for the uploaded photos (sic).

The author could rephrase that as follows:

This plugin permits everyone to inject SQL commands into the database and to do a cross site scripting attack.

You most certainly do not want to install this plugin even if you are in the mood for a photo contest.

I did not review the whole plugin, just login.php where I have found the XSS leak and view.php as well as viewimg.php where the SQL injection leaks are located. Most propably there are even more leaks as this plugin seems to be from an inexperienced PHP programmer.

The author has been notified at UTC 1022. Information applies to version 1.0 and 1.0.1.


The XSS leak is all too common:

$frompost_id = $_REQUEST['prid'];
<a href="<?php echo bloginfo('wpurl'); ?>/wp-content/plugins/wp-photocontest/login.php?post_id=<?php echo $frompost_id; ?>"><?php _e('Log In', 'wp-photocontest') ?></a>

There it is. A classic.

SQL injection in view.php and viewimg.php:

$post_id = $_REQUEST['prid'];
$q1 = "SELECT contest_id, start_date, end_date, contest_path, contest_name, intro_text, num_photo FROM ".$wpdb->prefix."photocontest_admin where post_id=$post_id";
$out = $wpdb->get_row($q1);

This is also a classic and a beginners mistake as well. There is no security whatsoever. Don’t consider this plugin to be safe when the mentioned leaks have been fixed!

What to do for plugin users

Deactivate and remove WP-PhotoContest immediately and wait for a revised plugin.

This issue has been resolved

WP Plugin Security: When the genius is out for lunch

I am in the mood for some more ranting… Why am I doing this? The low security level in the WordPress community aggravates me. And I care about the security of WordPress users out there. So here goes the next issue.

It’s a rather insignificant XSS security vulnerability but since the WP theme’s author runs the Website and his Swift theme for WordPress is getting more than 2000 downloads per week you might be interested in this.

There is a simple XSS hole in search.php of the Swift theme. GET parameter ‘s’ does not get sanitized or even touched. Go to, paste this into the search box and press enter for a live demo.

<style>*{visibility:hidden}html,body{visibility:visible}</style><div style=visibility:visible;line-height:150px;font-size:200px;color:green;position:absolute;top:0;left:0;padding:0;margin:0;background-color:red;width:10000px;height:10000px;margin-left:-200px;margin-top:-300px;padding-top:100px>XSS XSS XSS XSS XSS<script>alert(String.fromCharCode(88)+String.fromCharCode(83)+ String.fromCharCode(83))</script></div>

If a red page appears containing ‘XSS’ and a JS alert box containing ‘XSS’, the genius hacker has not yet fixed it.

You may want to check your own blog the same way. If it is vulnerable, search for something like this in your theme’s PHP files:

Search results for "<?php echo $_GET['s']; ?>"

and replace with

Search results for "<?php the_search_query(); ?>"

Search result page might still look ugly after a XSS attempt but at least nothing gets injected and rendered or even executed.

Update: Theme has been updated. Download the updated version with See for more information.

WP Plugin Security: WP Shopping Cart/WP eCommerce Security Holes

Another week, another security hole. This time I have found several holes in ajax-and-init.php from WP-eCommerce v3.7.4 aka WP Shopping Cart. It is the latest stable version. Let’s go.

The first issue is an unrestricted file deletion security breach. Remote attackers can trick a logged in WP user to click prepared links that can make the above mentioned script to delete files in webserver context. WP users must be logged in, a simple subscriber account would be sufficient.

The second issue is a SQL injection security breach. It is possible for remote attackers to trick a logged in WP user to click prepared links and have “Products List” items deleted and table “Products Files” truncated. As above, WP users must be logged in, a simple subscriber account would be sufficient.

There is at least another hole that enables remote attackers to change the plugin’s configuration under similar conditions.

What to do

Upgrade immediately to version 3.7.5 RC1.


The author of the plugin has been notified. I wonder though why these security leaks have not been mentioned in the 3.7.5 RC1 announcement… Judge for yourself.

UPDATE Oct 19, 2009: Leaks are still unfixed in the current stable version.

WP Plugin Security: WP-Ajax-Edit-Comments

Those who are WordPress admins should already know it: WordPress plugin quality often is quite worrisome. The latest smoking gun is WP Ajax Edit Comments. Normally I do not disclose security issues but this one is so obvious it freaks me out. Just to make clear: You do not have to be a seasoned programmer or admin to find bugs like this one. I did not check the whole potential of this vulnerability, maybe it also lets one inject SQL commands — I don’t know.

Let’s have a look. In file “comment-editor.php” (and in “move-comment.php” and “request-deletion.php” BTW) there’s this line:

$commentAction = $_GET['action'];

Yellow alert. But let’s look further before drawing a conclusion yet. $commentAction does not get touched anymore until this line occurs:

<input type="hidden" id="action" value="<?php echo $commentAction;?>" />

RED ALERT. This is a beginners mistake. The leak ist existing at least since version while the current version (as of this writing) is which also is vulnerable. It has been around for at least one year without someone noticing or fixing it despite being so obvious. According to WordPress plugin database it has been downloaded over 140,000 times so there may be tens of thousands of vulnerable WordPress installations.

Attackers could inject arbitrary HTML, like “THIS SHOULD NOT BE POSSIBLE”. Of course, criminals could create malicious pages this way and host them on remote WordPress sites.


How to fix it quick!

Replace this line

$commentAction = $_GET['action'];

with these lines:

$commentAction = $_GET['action'];
$commentAction = addslashes(preg_replace("/[^a-z0-9]/i", '', strip_tags($commentAction)));

It’s a quick and dirty fix. But it gets the job done. An even better approach would be to reject “action” parameter values with other characters than a-z.

The author of WP Ajax Edit Comments has been notified.

UPDATE: There is a new version that seems to be fixed.