Is this a reliable way to access options from a select element in PHP?

Go To StackoverFlow.com

1

I have this select input in my form that I want to access via PHP.

<div data-role='fieldcontain'>
    <label for='fruits' class='select'>Favorite Fruits</label>
    <select name='fruits[]' id='fruits' multiple='multiple' data-native-menu='false'>
        <option value=''>Favorite Fruits</option>
        <option value='1' selected='selected'>Apple</option>
        <option value='2' selected='selected'>Banana</option>
        <option value='3' selected='selected'>Cherry</option>
    </select>
</div>

By setting the name of the select element to "fruits[]", this works:

// |$fruits| is an array
$fruits = $_POST['fruits']

However, I am concerned about cleaning data from the form. Feeding post data into an array sounds insecure. What if, for instance, someone changes the select element into a text input element via Firebug and inputs malicious code into my program? I never call htmlspecialchars.

Are my security concerns valid? Why or why not?

2012-04-04 06:11
by John Hoffman
Yes your concerns are valid. Never trust user input. If you're printing it on the page you can use htmlspecialchars() to sanitize it, if your sticking it in a DB you should use mysql_real_escape_string() or the equivalent for your DB (if not using MySQL). Edit: of course, if all you're doing is adding the data to an array (not running it as a query, echo:ing it as HTML or passing it to eval then you've nothing to worry about - powerbuoy 2012-04-04 06:15
Thanks, how should I validate this item in the POST array then? This item itself is an array, so I can't directly call say htmlspecialchars on it because htmlspecialchars accepts a string - John Hoffman 2012-04-04 06:16
To run htmlspecialchars on every element of an array you can use array_walk: array_walk($fruis, 'htmlspecialchars') - powerbuoy 2012-04-04 06:19
@powerbuoy: If $fruits is a multi-dimensional array that won't work - Alix Axel 2012-04-04 06:25
@AlixAxel - well it shouldn't be in this case - powerbuoy 2012-04-04 06:29
@powerbuoy: But it might be if, for instance, someone changes the select element into a text input element via Firebug and inputs malicious code - quoting OP - Alix Axel 2012-04-04 06:30
You're right, my bad. Edit: in either case I'd run htmlspecialchars during output in the view, not in the controller (where I assume this is taking place) - powerbuoy 2012-04-04 06:31


1

They are valid indeed, if the data comes from the user input you need to sanitize it first.

In this case, a user can easily break your HTML or, even worse, inject some malicious XSS attack.

You need to sanitize the values, htmlspecialchars is enough in this case.


Nevermind, I understood you were populating the HTML select tag with options from user input, but this is not the case. PHP will only accept strings or arrays in POST data, so you need to make sure the data coming in is compatible with what you want to do with it. One possible solution would be to white-list the submitted values, functions like array_intersect might be useful here, for instance:

$allowed_fruits = array('Apple', 'Banana', 'Cherry');
$fruits = array_intersect($allowed_fruits, $_POST['fruits']);

This way, if the user submits "Strawberries" it will be ignored on the $fruits array.

You might also want to make sure that the array isn't multidimensional, like this:

if (count($_POST['fruits']) != count($_POST['fruits'], COUNT_RECURSIVE))
{
    // array is multidimensional, do not process
}

This of course, depends on your usage of the data but the white-list approach is always the most secure.

2012-04-04 06:16
by Alix Axel


1

Your code should be validating whether user input is in the expected format (isset, is_array, ...) and properly escaping it before sending it to the database, html output, logs, wherever else. Fundamentally there is very little difference in here between a user entered string and user entered array of strings.

Use mysql_real_escape_string (or even better PDO) to work with the database, htmlspecialchars to work with HTML output.

2012-04-04 06:17
by DCoder


1

That is the correct way to get the values, however, you are right to worry. You receive the values the way you suggest, then you use an appropriate method of sanitation: htmlspecialchars for displaying, mysql_escape for inserting into your DB, etc. You'll need to do that for each element in your array, but only at the time you're going to use it.

2012-04-04 06:17
by pocketfullofcheese
Ads