Archive for the 'Wordpress' Category

Well That Was Embarassing

It appears my blog was hacked along abouts July 29th, but I just now noticed.

The attacker managed to edit my wp-config.php file and attach WP-specific code that would include their remote file in the footer of each page load. I honestly probably never would have noticed, had I not checked my config file to see if the default WordPress cache were enabled or not.

Not only do I not load my own blog page frequently enough, but I don’t examine it closely enough either. The included code added a vast number of mortgage and debt consolidation spam links to the footer, all wrapped nicely in a hidden <div>. Since the code was valid and the destination server wasn’t slow enough to drag down the page, I shudder to think how long I could have been un-knowingly contributing to these spammers had I not randomly checked a file that’s generally set and forgotten.

If you’d like to check out the specific code that was appended to my wp-config.php file, I’ve dumped it on Pasteosaurus for future reference. In addition, the code inserted at the end of every page is here. As you can see, not only were they spamming for mortgages and debt consolidation, but they were referencing legitimate URLs for universities (Auburn and Vanderbilt). Why anyone would want to discredit an EDU in search results, I have no clue…

As for me, I’ll be keeping a better eye on my blog updates. I’ve switched to SVN so that it’s even easier than before, just to make sure there are no possible excuses next time a security release is made. I’ve also migrated this blog back to my Media Temple (gs) account temporarily, until I can finally fix some fallout from a botched Fedora Core 4 upgrade on my dedicated box1. If everything seems to be dragging, blame (mt)…

Finally, I’ve re-evaluated some of the plugins I’d been using. A lot of them I’d simply kept around for backwards compatibility, not wanting to break previous entries. This was a bad idea, since I was no longer paying attention to possible XSS vulnerabilities or stability patches for these plugins, leaving another potential opening for abuse on my blog. From now on, it’s the straight and narrow for me!

Not exactly how I wanted to spend my evening, but it could have been a lot worse… With un-restricted access to my blog and all it’s data, this is really the best possible outcome2.

  1. I really wish Plesk would supply a yum repo… [back]
  2. Yes, I do run regular backups of the database, so data loss would have been at a very minimum. It still would have been very painful. [back]

Modifying Allowed Upload Types in Wordpress

Several times recently in #wordpress, I’ve seen people asking how they could modify the list of allowed file types used in the file uploader on the Write Post page.

Since this information isn’t readily available (apparently) and to a lesser degree because I’m tired of not being able to find my previous code (causing me to re-type it all each time), I thought I’d throw together another quick WordPress hack guide.

Introduction

When you attempt to upload a file in WordPress (2.0+ I believe) that is not in the default list of acceptable file types1, you will receive the following error:

WordPress File Upload Error

As of WordPress 2.2, there are 35 allowed file types configured in the default install. While there’s no admin-based tool for editing this list (nor any plugins that I’m aware of), it’s not at all difficult to add your own…

The Code

Upload filetypes are checked by the function wp_check_filetype in wp-includes/functions.php (around line 1,000 in my current copy of trunk). Looking at the code, we see that the default array is passed into the upload_mimes filter, allowing you to easily add and remove types at will using a quick plugin hook.

So how do we do it? Well, first you need to add a new plugin hook. In your theme’s functions.php file, add this line:


add_filter('upload_mimes', 'custom_upload_mimes');

You can, of course, replace custom_upload_mimes with your own preferred function name. Just make sure it’s something unique that ideally won’t cause any naming conflicts later on2.

Now we’ve got a hook that tells WordPress to take the array of file types passed into the upload_mimes hook and hand it to the function custom_upload_mimes. Great, but where’s our function?

No problem, I’ve got it all ready for you. Open back up your theme’s functions.php file and toss in this code:


function custom_upload_mimes ( $existing_mimes=array() ) {

// add your ext => mime to the array
$existing_mimes['extension'] = 'mime/type';

// add as many as you like

// and return the new full result
return $existing_mimes;

}

Note that the function accepts the $existing_mimes array, adds a new file type (with the extension “extension” and of the mime type “mime/type”), and then returns the whole array.

Replace extension with your extension (no period before it, just the textual extension) and then Google to find out its mime type3.

Add as many new types as you like, simply by copying the example line and filling in your values. Also, make sure you name the function the same thing you used in the hook, assuming you don’t like my convention. Save your new functions.php file and you’re good to go!

Removing Existing Types

What if you want to remove an existing allowed type, instead of adding your own new type? Well, that’s even easier!

Replace the line $existing_mimes['extension'] = ‘mime/type’; with unset( $existing_mimes['extension'] ) and you’re done. For example, to prevent users from uploading .exe files, you would use:


unset( $existing_mimes['exe'] );

Good luck, hope this helps!

  1. For example, Microsoft Installer files are not allowed by default, so track down an .msi file and try to upload it for a quick test. [back]
  2. I like to use the prefix ‘custom_’ simply because it’s easy to tell later on that this is a custom modification. [back]
  3. Googling for “.zip mime type”, for example, should give you any number of sites listing a whole slew of mime types. Yours should be in the same <category>/<type> format as the others. Zip is “application/zip”. [back]

Using jQuery in Wordpress

It’s been a while since I actually encountered this particular nugget of advice1, but I thought I’d go ahead and make a quick post out of it anyway.

This is the kind of totally random and arbitrary development structure Wordpress has adopted that doesn’t really seem to ever be documented anywhere. If you don’t already know this kind of thing, you could very well be in store for major development and debugging headaches.

Anyway, here we go… If you’re using the built-in jQuery Javascript library that’s included in Wordpress since version 2.2, don’t use the handy-dandy $() function. In Wordpress, $() is reserved for the Prototype library, which is also bundled2.

Instead, for interoperability, be sure to use jQuery() instead, which should accomplish the same thing.

A bad example:


var username = $('#username').val();

If Prototype were to be loaded on the page this snippet of JS is running on, it would throw an error, since it uses a different pattern for selecting DOM elements.

A good example:


var username = jQuery('#username').val();

This line should work on any page, regardless of library conflicts. It’s a couple extra characters to type, but in the end it’s really for the best - you get portability, and it’s more self-explanatory which library is being used when you go back to look at this code in 6 months.

I’m planning another, similar, Javascript-related post as soon as I get a few more minutes to make it coherent. Stay tuned, and happy coding!

  1. Pointed out by rob1n in #wordpress, BTW. [back]
  2. In all fairness, I suppose this makes sense. Prototype was added first. [back]

How Strong is YOUR Password?

You’ve probably read it over on the Wordpress.com blog by now - they’ve taken a step up in password security by adding a meter that gauges the strength of a user’s password as they change it.

Well now you don’t have to use Wordpress.com to make sure your users are aware when their passwords stink - the Password Strength plugin provides the same functionality for stand-alone Wordpress 2.2+ blogs.

Password Strength is a stand-alone port of the Wordpress.com feature written by Donncha1 and uses the same Password Strength Meter jQuery goodness, written by Phiras!

Download
Ready? Set. Goooooo! password_strength-1.0

Note that this plugin requires Wordpress 2.2, as it relies upon the bundled jQuery Javascript library.

  1. Or is it that cat that does all the work? I never can tell… [back]

Changing the length of the_excerpt() in Wordpress

How can I change the length of the_excerpt() in Wordpress without editing core files?

Well, first we need to figure out exactly where the excerpt text is truncated. Checking wp-includes/default-filters.php, around line 128 we see:

add_filter('get_the_excerpt', 'wp_trim_excerpt');

Ok, so that’s how it’s cut off. The first step in our fix is to prevent the default function from running and truncating the text at the default length. The easiest way to do this? Simply remove the filter by adding a line to your theme’s functions.php file:

remove_filter('get_the_excerpt', 'wp_trim_excerpt');

Great. So now we’ve got the_excerpt() looking exactly like the_content(). Now we need to create our own pretty little function to handle truncating the_excerpt to the length we need. Since those crazy Wordpress devs have already thought of everything, we’ll use their original function as a template for our new one. The original function can be found in wp-includes/formatting.php, around line 779:

[php]
function wp_trim_excerpt($text) { // Fakes an excerpt if needed
global $post;
if ( ” == $text ) {
$text = get_the_content(”);
$text = apply_filters(’the_content’, $text);
$text = str_replace(’]]>’, ‘]]>’, $text);
$text = strip_tags($text);
$excerpt_length = 55;
$words = explode(’ ‘, $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, ‘[...]‘);
$text = implode(’ ‘, $words);
}
}
return $text;
}
[/php]

See the line $excerpt_length = 55;? That’s the one we want to change!

Take your new wp_trim_excerpt function and stick it in your theme’s functions.php file. Be sure to rename it to something unique. You should end up with something similar to this:

[php]
function custom_trim_excerpt($text) { // Fakes an excerpt if needed
global $post;
if ( ” == $text ) {
$text = get_the_content(”);
$text = apply_filters(’the_content’, $text);
$text = str_replace(’]]>’, ‘]]>’, $text);
$text = strip_tags($text);
$excerpt_length = 75;
$words = explode(’ ‘, $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, ‘[...]‘);
$text = implode(’ ‘, $words);
}
}
return $text;
}
[/php]

Note that I only made two changes: 1) renamed the function to “custom_trim_excerpt”, and 2) changed the excerpt_length to 75.

Great, we’re almost there! One step left. Now we have to tell Wordpress to use our new custom function to truncate the_excerpt. We’ll do this by adding a new filter, similar to the one we removed at the very beginning. Stick this line in your theme’s functions.php file:

add_filter('get_the_excerpt', 'custom_trim_excerpt');

Be sure to substitute your new function’s name, assuming you didn’t use the same one I did, and you should be all set!

Note: This guide was written using Wordpress 2.2. The exact procedure may vary with versions, but should be fairly similar.