About the Author

Chris Shiflett

Chris Shiflett is an author and speaker who leads the web application security practice at OmniTI.


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.

5 Comments

1. GWild's GravatarGWild said:

Nice podcast. Thanks for posting it.

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


2. S's GravatarS 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's GravatarIvo 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's GravatarBigDaddy 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's Gravatartapeworm 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


Post A Comment

Personal Details and Comment

Style Guide

Line breaks are converted to paragraphs. Also use:

  • <a href="" title="">text</a>1
  • <em>text</em>
  • <blockquote><p>text</p></blockquote>
  • <code>2  <?php  if ($foo) {      $foo = TRUE;  }  ?></code>
  1. Note: <code> can be used inline (e.g. in paragraphs) or in a block as shown. Include whitespace and newlines in blocks.

Please enter Chris (my first name) below. This is a primitive spam prevention technique, and I apologize for the inconvenience.

Preview and Submit

Upcoming Talks

php|tek

19 - 22 May 2009

At Sheraton Gateway Suites Chicago O'Hare, Chicago, Illinois.

OSCON

20 - 24 Jul 2009

At San Jose McEnery Convention Center, San Jose, California.

New Comments

Ronald wrote:

A little hard for a rookie like me, but useful. I also thought you'd like to know there is a grea...

Posted in A rev="canonical" HTTP Header
Alex wrote:

Aren't you forgetting that the session will expire if _write() is never called? That excludes ...

Posted in
Andy Mabbett wrote:

@Chris Shiflett, #4, belatedly: Google only accepts rel=canonical within the same domain. My s...

Posted in A rev="canonical" HTTP Header
Kenneth Udut wrote:

I've implemented this rev="canonical" idea on http://free.naplesplus.us in the hopes that it catc...

Posted in Save the Internet with rev="canonical"
Mark wrote:

After reading your article and all the comments, what I got out of this was that sessions are not...

Posted in

Browse Comments