About the Author

Chris Shiflett

Hi, I'm Chris, a web developer and a founding member of Analog. I live and work in Brooklyn, NY.


PHP Advent Calendar Day 15

Today's entry, provided by Paul Reinheimer, is entitled Channels and Output.

Paul Reinheimer

Name
Paul Reinheimer
Blog
blog.preinheimer.com
Biography
Born in Vancouver, raised in Ontario, educated in Windsor, currently roaming the streets of beautiful Montreal. When not fighting off crazy Internet vixens, Paul pays his hosting and Internet bills by taking care of training for php|architect, launching his own projects like funcaday, and speaking at various conferences.
Location
Montreal, Canada

When getting started with PHP programming, we memorize rules that those who came before us hand down, such as:

  • Use mysql_real_escape_string() when you're sending data to a MySQL database.

  • Use htmlentities() when you're outputting data to a web page.

The rules might not initially make a lot of sense, but given time, we learn.

The primary reason we have such rules isn't that MySQL does a poor job of interpreting data and browsers are silly, but that we're sending data and commands (or data and metadata) through the same channel. A single stream of information carries information like php.net and instructions like <title> tags. With a single stream that carries both the instructions and the data, the receiving system might misinterpret one for the other. This misinterpretation is the basis of problems like cross-site scripting and SQL injection.

To protect against these attacks, you have two choices. You can either separate the streams or escape the data to avoid confusion. When you use prepared statements with SQL, you are essentially separating the streams; the queries you send to the database are sent separately from the data, maintaining the necessary distinction.

Using separate channels is secure and convenient, but it isn't always an option. An alternative option is to escape the data. Escaping is deceptively simple; determine which characters might be misinterpreted as instructions (special characters), and escape those characters to preserve their original meaning. Native functions exist for most common contexts, such as htmlentities() for HTML and mysql_real_escape_string() for MySQL.

Be sure to take character encoding into account. For HTML, The Content-Type header should indicate the same character encoding as htmlentities(). For MySQL, mysql_real_escape_string() maintains this consistency for you.

The next time you're sending data to an external resource, see if it's possible to separate the channels. If not, refer to the external resource's documentation to determine which characters are treated in a special way, and escape your data accordingly.

About This Post

PHP Advent Calendar Day 15 was posted on Sat, 15 Dec 2007 at 23:57:43 GMT.

2 Comments

1. Jorrit Schippers's GravatarJorrit Schippers said:

Nowadays I use htmlspecialchars(), because entities such as &euml; are not allowed in XHTML, and if you have your character encodings right, ë should work just as well as &euml;

Sun, 16 Dec 2007 at 11:09:56 GMT Link


2. Lars Gunther's GravatarLars Gunther said:

Could be better:

It is time to teach prepared statements. That is even better than mysql_real_escape_string(). I teach PHP to newbies as a job. Nowadays I start with PDO, and make only mention the mysql interface.

I good:

Otherwise I agree, and I think it's important to explain the principle, as people are confusing filtering with escaping all the time.

Sun, 16 Dec 2007 at 11:12:04 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

Kiwi Foo Camp

12 - 14 Feb 2010

At Mahurangi College, Warkworth, New Zealand.

Webstock

15 - 19 Feb 2010

At Wellington Town Hall, Wellington, New Zealand.

ConFoo

10 - 12 Mar 2010

At Hilton Montréal Bonaventure, Montréal, Canada.

South by Southwest

12 - 16 Mar 2010

At Austin Convention Center, Austin, Texas.

New Comments

Sujoy wrote:

Chris, this is the first time I'm visiting your blog! Your 2009 Highlights is really great! Fanta...

Posted in 2009 Highlights
Giovanni wrote:

Hi Chris! First of all, my persona thanks for all your article about PHP security! it's really u...

Posted in The Truth about Sessions
Chris Shiflett wrote:

Thanks, John. Friendly and trustworthy are high compliments. Much appreciated. :-) Sorry about...

Posted in 2009 Highlights
Eric B wrote:

Hi Chris, Thanks for this clean, concise article on this topic. You are a life saver! -E

Posted in Guru Speak: Storing Sessions in a Database
Radoslav Stankov wrote:

wow, I looks like 2009 wasn't very boring year. p.s. I didn't know you too are Arsenal fan.

Posted in 2009 Highlights

Browse Comments


Work and Books

Analog Essential PHP Security HTTP Developers Handbook