NYCPHP Meetup

NYPHP.org

[nycphp-talk] PHP Form Validation

Chris Shiflett shiflett at php.net
Fri Sep 2 12:50:46 EDT 2005


Billy Reisinger wrote:
> Correct me if I'm wrong here, folks, but using a $_POST['variable']
> directly in a form is no more or less vulnerable to attack than
> using a different variable that is a reference to a $_POST variable.

That's right. In other words, the following is an example of a 
cross-site scripting vulnerability if $username is tainted:

echo "<p>Welcome, $username!</p>";

It's very easy to make a mistake that taints a variable without being 
obvious. For example, sometimes data is massaged several times before 
being used:

$user = $_POST['user'];

/* ... */

$user_array = explode(',', $user);

/* ... */

$name = $user_array[3];

/* ... */

list($first_name, $last_name) = explode(' ', $name);

/* ... */

echo "<p>Welcome, $first_name!</p>";

That's the best example I can think of on the fly. :-)

The point is that it's very easy to make a mistake - we all do it. 
That's the main reason why I try to adhere to practices that can help me 
make fewer mistakes.

I use $_POST sometimes in articles and talks just to make it obvious 
that the data is tainted and to make the example attacks simple and 
straightforward. That's why it's disappointing to see an article with 
such an obvious vulnerability.

> If you want to carry over form values after errors or across
> multiple form pages (i.e. preserve state), you have to reference
> these $_POST variables eventually, in some form or fashion. In
> this sense, ALL forms are vulnerable to hacks.

That's definitely not true. Consider a username form field. This is 
basically what the article in question recommends:

<input type="text"
        name="username"
        value="<?php echo $_POST['username']; ?>" />

Contrast that with this:

<?php

header('Content-Type: text/html; charset=UTF-8');

$clean = array();
$html = array();

if (isset($_POST['username'] &&
     ctype_alnum($_POST['username']))
{
     $clean['username'] = $_POST['username'];
}
else
{
     $clean['username'] = '';
}

$html['username'] = htmlentities($clean['username'],
                                  ENT_QUOTES,
                                  'UTF-8');

?>
<input type="text"
        name="username"
        value="<?php echo $html['username']; ?>" />

There's an enormous difference between the two.

Chris

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



More information about the talk mailing list