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