In the spirit of improving the quality of open source software, I’ve decided to launch a whole new category here on wonko.com. I’m calling it Crappy Code. Whenever I come across a really crappy piece of code in an open source application, I’ll write a cantankerous, insult-laden post all about how crappy it is and then, when applicable, I’ll offer up a suggestion for improving said code.

For our first installment in this series, we’ll turn to WordPress. If I had to list all the things I hate about WordPress, I’d probably kill myself instead. But here’s an example of the sorts of things that might be on that list if my suicide attempt were to fail:

  1. They have a stupid motto. “Code is poetry”. Blah blah. I’d be less annoyed by this if their code was actually good, but the fact that it sucks just annoys me even more.
  2. WordPress is one of those applications that uses 100 lines of code to accomplish a task that could have been accomplished in 10 lines if the developers had bothered to put some fucking thought into it.
  3. Nobody who uses WordPress actually gives a shit about how crappy the code is, so it’s insanely popular. Wound: check. Salt: check.

So now that we’ve established that I’m insanely biased, let’s get to the part where I make fun of some code. It was pretty tough finding just one thing to make fun of. I have a feeling WordPress is going to show up quite a lot in future Crappy Code posts. But to get things started I wanted something short, sweet, and simple. Lo and behold, I found it.

WordPress 1.5.2; wp-includes/wp-db.php; line 76:

// ====================================================================
//  Format a string correctly for safe insert under all PHP conditions

function escape($str) {
  return addslashes($str);
}

Oh dear God.

The comment is what really gets me. What genius came to the conclusion that addslashes would make all possible strings safe for use in SQL queries under all possible conditions? The addslashes function just puts a backslash (\) in front of single-quotes (‘), double-quotes (“) and NUL characters. And depending on the value of PHP’s magic_quotes_sybase setting, it might escape single-quotes with another single-quote rather than a backslash. What it doesn’t do is escape newlines, carriage-returns, or the control character \x1a, all of which need to be escaped when sending string values to MySQL.

Instead of addslashes, they should be using mysql_real_escape_string, which actually does escape every unsafe character “for safe insert under all PHP conditions”. Their code should look like this:

function escape($str) {
  return mysql_real_escape_string($str, $this->dbh);
}

WordPress is one of the most widely used PHP applications in the world. They have a history of SQL injection vulnerabilities. You’d think they’d know by now which function to use for escaping strings being sent to MySQL.

Update: A helpful reader has pointed out that the issue was fixed way back in July and the fix will be in the 1.6 release.

Comments

See here.

While not in the current stable release, it will be in 1.6.
Gravatar icon
Tuesday October 11, 2005 @ 12:24 AM (PDT)

Glad to hear it.

Gravatar icon
Tuesday October 11, 2005 @ 10:23 AM (PDT)
I use wordpress. USE is the keyword. I have many a time stared in shock at the code and wondered "what the hell is this"? Why you would want to admit you are a developer for the codebase is beyond me.

But then I realize: "eh - it works."

Its the same sorta feeling I get when I have to use windows for a day. All icky in my shorts.
Gravatar icon
beegee
Wednesday October 12, 2005 @ 12:50 AM (PDT)
I sometimes wish I could ignore crappy code and just focus on the fact that something works, but I can't. No matter how hard I try.

The great thing about Windows is that I can't see the source, so it doesn't bother me as much.
Gravatar icon
Wednesday October 12, 2005 @ 10:36 AM (PDT)

Hey Wonko, have you looked at your main page in IE lately? The postings are pushed down the page, showing a lot of unnecessary white space. It doesn't happen in Firefox. Just an FYI.

Gravatar icon
Wednesday October 12, 2005 @ 07:50 PM (PDT)

No, I have not looked at my main page in IE lately. I also have not looked at my main page in Mosaic lately.

Gravatar icon
Wednesday October 12, 2005 @ 08:06 PM (PDT)

*snigger*

Gravatar icon
Cena
Thursday October 13, 2005 @ 03:46 AM (PDT)
1174

function getVar($var)
{
if (isset($_POST[$var]))
return $_POST[$var];
elseif (isset($_GET[$var]))
return $_GET[$var];
else
return "";
}
63

set_magic_quotes_runtime(0);

if (get_magic_quotes_gpc() == 0)
{
function magicSlashes($element)
{
if (is_array($element))
return array_map("magicSlashes", $element);
else
return addslashes($element);
}

// Add slashes to all incoming GET/POST data. We don't care about
// cookies.
$_GET = array_map("magicSlashes", $_GET);
$_POST = array_map("magicSlashes", $_POST);
}
Gravatar icon
Sunday October 16, 2005 @ 04:29 PM (PDT)

You have done exactly the same thing in Poseidon??? As i can see in the code above you have done exactly the same thing. All things you get via getVar() you put directly in the database.

You should see over your own code before you are whining at others code ;)

The getVar function comes from functions.php and line 1166 to 1174

The magic_quotes stuff comes from startup.php and line 47 to 63

I try to post everything again in the hope of stuff won't disappear again (that's why the previous post is incomplete).

Gravatar icon
Sunday October 16, 2005 @ 04:42 PM (PDT)
Allow me to quote myself from a few days ago:
PHP makes it ridiculously easy to write messy, unsecure, unmaintainable code that nevertheless produces beautiful results. I should know; I've written my fair share of crappy PHP code.

The code you're referring to in Poseidon was written two years ago, and yes, it's bad. I've written tons of shitty code, but I've learned from my mistakes.

Should I not be allowed to share what I've learned because I once made the same mistakes that I'm trying to teach others not to make?

Gravatar icon
Sunday October 16, 2005 @ 08:46 PM (PDT)
Sure, you are allowed to write shitty code. (And i can agree to you, poseidon is full with some shitty code to :P)

But i didn't think that Poseidon is 2years old. So i'm sorry.

// Jonas
Gravatar icon
Monday October 17, 2005 @ 06:40 AM (PDT)

It seems you do look at your page in IE once in a while...

Gravatar icon
Monday November 14, 2005 @ 04:34 PM (PST)
addslashes is indeed sufficient to protect against SQL injection in MySQL. It doesn't guarantee that the data inserted is as it should be, but given that their comment says it's for "safe insert" as opposed to "correct insert", I don't really see a problem.

Or perhaps you can show me an example of SQL injection using new lines as opposed to single or double quotes? ie. one that works on strings that have been passed through addslashes and not mysql_real_escape_string?
Gravatar icon
yawnmoth
Wednesday December 07, 2005 @ 06:13 PM (PST)
Oh - and to quote from php.net:

'safed' claims that addslashes() is no good for securing MySQL queries, as it does not escape \n and \r. However the MySQL reference (http://dev.mysql.com/doc/refman/4.1/en/mysql-real-escape-string.html) states "Strictly speaking, MySQL requires only that backslash and the quote character used to quote the string in the query be escaped. This function quotes the other characters to make them easier to read in log files."

So addslashes() should be fine from that point of view.

source Anyway, given all this, I think you are just as misinformed as you claim the WordPress developers to be.
Gravatar icon
yawnmoth
Wednesday December 07, 2005 @ 06:16 PM (PST)

Allow me to quote myself:

The comment is what really gets me. What genius came to the conclusion that addslashes would make all possible strings safe for use in SQL queries under all possible conditions?

If that comment hadn't been there, I probably would have moved on. But if you're going to write a comment that definitively declares your code to be bulletproof, your code had better actually be bulletproof or it's going to bite you in the ass eventually.

From an SQL injection standpoint, addslashes works fine for MySQL. But if you happen to be the system administrator and you have to occasionally work with MySQL query logs, you're going to be pretty annoyed to find queries with unescaped newlines mucking up the log and making it hard to read.

It takes no extra effort to use mysql_real_escape_string instead of addslashes. There's no excuse not to.

Gravatar icon
Wednesday December 07, 2005 @ 09:02 PM (PST)

I can agree with that - that given a choice between the two, it's preferable to use mysql_real_escape_string :)

Gravatar icon
yawnmoth
Thursday December 08, 2005 @ 12:54 AM (PST)

Hey there — looks like the link to "Crappy Code" in the first paragraph of your post is broken.

Gravatar icon
Thursday October 26, 2006 @ 05:03 AM (PDT)

Oops. Thanks. This post was written when I was using the previous generation of my blog engine, which used a different URL scheme.

Gravatar icon
Thursday October 26, 2006 @ 08:54 AM (PDT)
"It takes no extra effort to use mysql_real_escape_string instead of addslashes. There's no excuse not to."

Except that mysql_real_escape_string() needs a database connection in order to actually add slashes.

See: http://php.net/mysql_real_escape_string
Gravatar icon
Saturday November 04, 2006 @ 04:57 PM (PST)

Wonko you're a legend... this thread is pissfunny.

Gravatar icon
Thursday July 05, 2007 @ 11:10 AM (PDT)

Hello, you say that : "From an SQL injection standpoint, addslashes works fine for MySQL. But if you happen to be the system administrator and you have to occasionally work with MySQL query logs, you're going to be pretty annoyed to find queries with unescaped newlines mucking up the log and making it hard to read."

It seems like SQL injection is still possible with addslashes(). I found this webpage about this : http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string There is many problem with multi-byte character that addslashes() don't handle correctly, so many quote can pass it.

This kind of strings can do it : # $_POST['username'] = chr(0xbf) . # chr(0x27) . # ' OR username = username /*';

Gravatar icon
man with no name
Wednesday January 02, 2008 @ 02:13 PM (PST)

Sorry, I don't know why but the newline have been drop :) The strings is :
$_POST['username'] = chr(0xbf) .chr(0x27) .' OR username = username /*';
And this is a the clickable link ;)

Gravatar icon
man with no name
Wednesday January 02, 2008 @ 02:17 PM (PST)

Or is it just an issue again? I've only just started looking at wordpress-mu, and this is not encouraging stuff to see. Here's the first line of the current escape function:

return addslashes( $string ); // Disable rest for now, causing problems

What kind of 'problems' were being caused by mysql_real_escape_string?

Gravatar icon
martin
Thursday January 10, 2008 @ 08:58 AM (PST)

Wonko, until you are the lead architect of probably the world’s most popular piece of open source code I think you should keep your comments to yourself.

I am an experienced PHP developer working on Windows and coding in Dreamweaver. I am well recognised as a God among folk who can only code HTML and CSS. They find it really hard to modify WordPress because it is so advanced. People who code WP templates are highly regarded for the skill it takes to work around my PHP which bundles out elegantly concatenated HTML. The thing that makes WordPress great more than anything else is the fact that I have files with HTML, PHP, JavaScript, XML and RSS all mixed within each other. You’ve got to be shit hot to pull that off. Some people say its a miracle WordPress even works.

Looking down on your from the WordPress bummers fan wave,

Matt Bunglecode.

Gravatar icon
Friday March 14, 2008 @ 01:54 PM (PDT)

!

“The thing that makes WordPress great more than anything else is the fact that I have files with HTML, PHP, JavaScript, XML and RSS all mixed within each other. You’ve got to be shit hot to pull that off.”


Given just about any PHP script you look at includes HTML and Javascript, and XML/RSS are nothing exciting, this comment can’t stand for a lot.

Gravatar icon
Joe
Wednesday October 22, 2008 @ 10:47 PM (PDT)

That Matt Bunglecode comment is funny stuff.. “I am well recognised as a God among folk who can only code HTML and CSS” – Code… hahaha.. dreamweaver too, oh lordy..

Ok, back to life now.

Gravatar icon
Sunday February 08, 2009 @ 04:58 AM (PST)

“The thing that makes WordPress great more than anything else is the fact that I have files with HTML, PHP, JavaScript, XML and RSS all mixed within each other. You’ve got to be shit hot to pull that off.”

No… you have to be hot shit to get XML to make you a bacon buttie and run an air traffic control system. HTML, PHP, JS, XML and RSS are MEANT to work together. PHP is designed to have HTML inside it, or it inside HTML. JavaScript is an HTML addon to all intents and purposes. XML is just a mostly-compatible markup language and RSS is an aggregation system to be built into web pages.

WordPress does the job, but it is indeed a sorry attempt at a software design. Its problem is that it simply wasn’t designed properly, too much is being added on by incompetent developers; all too often outside of the original scope and not fitting in with the architechture.

As for WP being ‘too advanced to modify’ – just no. It’s difficult if you don’t know PHP, but anyone with a background in any C-based language (or the majority of languages currently used) will find their way around with the minimum of effort.

Gravatar icon
Jon
Sunday February 22, 2009 @ 07:55 PM (PST)

“I am well recognised as a God among folk who can only code HTML and CSS. They find it really hard to modify WordPress because it is so advanced”

Was it you or one of your minions who hatched this article about writing unmaintainable code ? :)

I tend to agree with this new found religion. Creating something so “advanced” will guarantee yourself a lifetime of employment :))

Gravatar icon
Adrian
Saturday March 21, 2009 @ 07:19 AM (PDT)

I have to say, when I stumbled upon this, quite accidentally, by trying to find some way to force Wordpress to escape my string properly, I was at first, taken aback. You must understand, that I’ve used Wordpress almost exclusively for several years now and have been impressed with its flexibility.

However, I have only pored through those sections of code-base which I have had to, and never came across this problem (though I see it is now fixed). And so, after the initial sting wore off, I found some respect.

So now I leave, ever so slightly impressed.
-cheers!

Gravatar icon
Sharon
Thursday October 08, 2009 @ 11:07 AM (PDT)

You have to admire the chutzpah of anyone claiming to be a coding god, but still admitting to use Dreamweaver. My guess is that Matt is trying to use irony, which doesn’t always come over well in the written word.

Gravatar icon
Monday October 12, 2009 @ 03:47 AM (PDT)
New comment

required, won't be displayed

optional

Don't type anything here unless you're an evil robot:


And especially don't type anything here:

Basic XHTML (including links) is allowed, just don't try anything fishy. Your comment will be auto-formatted unless you use your own <p> tags for formatting. You're also welcome to use Textile.

Copyright © 2002-2010 Ryan Grove. All rights reserved.
Powered by Thoth.