About the Author

Chris Shiflett

Hi, I’m Chris, a web craftsman making things like Mapalong & Brooklyn Beta with my friends at Analog.


Episode One

No, I'm not talking about Star Wars. The first episode of Ask Chris is now online. In this episode, I am asked about a comment I made during my talk at PHP West. During the talk, someone asked when stripslashes() should be used, and I said it should never be used. I was being a bit cheeky, but I thought it was funny. :-) I went a bit further, noting that if you ever find yourself removing the escaping of something, you've probably screwed up somewhere. I didn't substantiate this remark (because it was tangential to the current topic), so many people have, understandably, questioned it.

Based on the comments, I apparently haven't clarified the issue very well, so let me explain further.

When you send data to a remote system, it often enters a context where it might be interpreted to be something other than data (there are caveats, such as when you're using bound parameters). In order to preserve the data when it enters this other context, you need to escape it. This means different things in different contexts, but the basic idea is consistent.

One common example is the use of data in an SQL query. For example:

<?php 

$sql
= "INSERT
        INTO   users (last_name)
        VALUES ('$last_name')"
;

?>

If $last_name is O'Reilly, this query becomes:

INSERT
INTO   users (last_name)
VALUES ('O'Reilly')

That's going to break, because the ' in O'Reilly affects the format of the SQL query - it's considered to be something other than data. In order to avoid this, it needs to be escaped. If you're using MySQL, you use mysql_real_escape_string() for the escaping, so O'Reilly becomes O\'Reilly. This makes the query look a bit better:

INSERT
INTO   users (last_name)
VALUES ('O\'Reilly')

Now, here's the tricky part. Guess what is stored in the database. Easy, right? The answer is O'Reilly (sans backslash). If you don't believe me, try it for yourself. Sure, you can stripslashes() on O'Reilly, but there are no backslashes to be stripped, so it's pointless (plus some day your data might really have some backslashes in it). Now, imagine my surprise when I read this comment:

Of course, you face the problem of what do to if you already have a large number of records already stored in a database that have NOT been escaped with mysql_real_escape_string().

In the words of enygma:

Ow. My eyes.

About this post

Episode One was posted on Wed, 10 Aug 2005 at 03:29:18 GMT. Follow me on Twitter.

5 comments

1.GWild said:

Nice podcast. Thanks for posting it.

Wed, 10 Aug 2005 at 12:30:23 GMT Link


2.S said:

It seems to me, after reading the original comments, that the poster (Big Daddy) has data in his database that IS escaped.

(he's got "o\'reilly" in his database, because it was inserted as "o\\'reilly")

Perhaps this is because the original inserter did something like this:

"INSERT .... (". mysql_real_escape_string($_POST['name']) .", ...)" after the data has been pre-escaped (poorly) with e.g. magic_quotes_gpc.

The appropriate solution to this is NOT to stripslashes() when selecting the data, but instead to fix the data (and THEN, stripslashes() can (probably, depending on the details of when the extraneious "\" appears) be used appropriately).

S

Wed, 10 Aug 2005 at 15:08:43 GMT Link


3.Ivo Jansch said:

Or, use an extra quote to escape it, as per the ANSI standard. This works in most databases. So convert O'Reilly to O''Reilly.

\' works on most databases, but perhaps not on all (I don't know if I remember this correctly, but wasn't it in Mysql <3.23 that the \ would get stored in the db with the \' approach?)

Wed, 10 Aug 2005 at 20:37:33 GMT Link


4.BigDaddy said:

S nailed it on the head...and my eyes do hurt when I look at the data that's been stored. Ow.

I was just expressing my frustration and perhaps a small overreaction to Chris' statement about how to never use stripslashes. Some things get overlooked during a deathmarch to get a project with almost no documentation done.

Thu, 11 Aug 2005 at 01:48:19 GMT Link


5.tapeworm said:

according to the manual the proper usage of mysql_real_escape_string() is in conjunction with sprintf(). my apologies if i've overlooked something simple, but how would you recommend one use this safe example in combination with mysql's DATE_FORMAT?

Sat, 20 Aug 2005 at 23:59:33 GMT Link


Hello! What’s your name?

Want to comment? Please connect with Twitter to join the discussion.


Work and Books

Analog Essential PHP Security HTTP Developer's Handbook