Re: Explanation in Shiflett's PHP Security Briefing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



afan@xxxxxxxx wrote:
I got the point Chris was making: never believe _GET/_POST and use ctype_alnum(), mysql_real_escape_string(), htmlentities() - and I already started :) (Thanks Chris that was great for us beginners, already posted on few Bosnian php forums :))

You're welcome. :-)

I must point out that the functions you just mentioned fall into two separate categories.

Filtering:
ctype_alnum

Escaping:
htmlentities()
mysql_real_escape_string()

My question though was is the difference in code I mentioned just a "habit of writing code" or there is some more? Some security issues too?

Well, the discipline of web application security involves both practical and theoretical aspects. For example, the following two code snippets are not equal:

<?php
if (ctype_alnum($_POST['username'])
{
    $_POST['username'] = htmlentities($_POST['username']);
    echo "<p>Hi, {$_POST['username']}!</p>";
}

?>

<?php
$clean = array();
$html = array();
if (ctype_alnum($_POST['username']))
{
    $clean['username'] = $_POST['username'];
    $html['username'] = htmlentities($clean['username']);
    echo "<p>Hi, {$html['username']}!</p>";
}
?>

They both do the exact same thing - they welcome a user according to the username provided in a POST request. The difference is not a technical one - it's a difference in theory.

By storing only filtered data in $clean, and by storing only filtered data that has also been escaped for use in HTML in $html, I know that I can safely send the value of any element within the $html array to the client (browser).

This difference is hard to appreciate with such a simplistic example, especially when the code is not spread out, but it mitigates the damage that can be done when a developer makes a mistake. The worst-case scenario is that $html['username'] does not exist - this is better than it being tainted (both can be caused by the same mistake).

A developer can always output $_POST['username'] raw, but the idea is that you can modify your approach to make things as easy as possible for the security-conscious developers.

(This idea is also why I never recommend storing filtered data back into $_POST - you want to foster the natural suspicion that developers have for data stored therein, not deteriorate it.)

Let's try this way: we have a case of a form for storing registrant info in DB. After submitting we have
$_POST['name']
$_POST['address']
$_POST['city']
$_POST['state']
$_POST['zip']
$_POST['email']
$_POST['phone']

To store submitted info to DB I would (now) use following code:

$name = mysql_real_escape_string($_POST['name']);
$address = mysql_real_escape_string($_POST['address']);
$city = mysql_real_escape_string($_POST['city']);
$state = mysql_real_escape_string($_POST['state']);
$zip = mysql_real_escape_string($_POST['zip']);
$email = mysql_real_escape_string($_POST['email']);
$phone = mysql_real_escape_string($_POST['phone']);

mysql_query("insert into info values (NULL, '$name', '$address', '$city', '$state', '$email', '$phone')");

You forgot to filter your input. Shame! :-)

Escaping alone can save you in many cases, but always filter input and escape output.

Hope that helps.

Chris

--
Chris Shiflett
Brain Bulb, The PHP Consultancy
http://brainbulb.com/

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux