4
\$\begingroup\$

I was hacking around this morning and wanting to use automatically generate safe-to-use variables from $_POST. Probably not the best use of extract() and compact(), but extract() allowed me to prefix variable names and compact(explode()) seemed like a neat way to stick everything back into an array after being prefixed.

function sanitizeForm($formVars) {
    // prefix $_POST vars so attacker can't try and guess existing
    extract($_POST, EXTR_PREFIX_ALL, 'form');
    // put the form variables back into an array
    $inputArray = compact(explode(' ', $formVars));
    $cleanInput = array();
    foreach($inputArray as $key => $value) {
        $cleanInput[$key] = htmlspecialchars($value);
    }
    return $cleanInput;
}

The test form I used simply posted firstname, lastname, and comments. Here's the PHP:

if(isset($_POST['submit'])) {
    $test = sanitizeForm('form_firstname form_lastname form_comments');
    echo('<pre>');
    print_r($test);
    echo('</pre>');
}

Submitting 'test' for both firstname and lastname with the script in comments:

Array
(
    [form_firstname] => test
    [form_lastname] => test
    [form_comments] => <script>alert('xss')</script>
)
\$\endgroup\$
3
\$\begingroup\$

You should first ask yourself this: Why am I sanitizing input in this way?

Let's say I have a login form, and the user enters his credentials, an email and a password. The email will be queried against the database, to figure out the user's hashed password (You are hashing your passwords, right?!), and the password would be hashed, to be compared against that hash.

Both of those fields will never be outputted to HTML, the password is never kept in plain-text form for very long, and the username is queried against the database and then discarded. So why should you escape them for HTML?


Sanitizing (or more accurately named, Escaping), contrary to popular belief should not be done when you receive your input. It should be done right before you output it. Because at the time you receive your input, you have no idea where it's going to be used. It could be outputted to HTML (in which case it needs htmlspecialchars()), it could be outputted to JSON for an AJAX response (in which case it needs json_encode()), it could be stored in the database (in which case it needs prepared statements).

The general rule is: You escape as late as possible. HTML strings should be escaped right before they get echoed onto an HTML page.


What you should be doing when receiving your input, and as early as possible, is validating the input, i.e. making sure the input matched what you expect in format, and in business logic. Format means "This is a valid email address", and business logic means "This comment that the user is trying to edit, really belongs to him".

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.