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?
htmlspecialchars
on it because htmlspecialchars
accepts a string - John Hoffman 2012-04-04 06:16
htmlspecialchars
on every element of an array you can use array_walk
: array_walk($fruis, 'htmlspecialchars')
- powerbuoy 2012-04-04 06:19
htmlspecialchars
during output in the view, not in the controller (where I assume this is taking place) - powerbuoy 2012-04-04 06:31
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.
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.
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.
htmlspecialchars()
to sanitize it, if your sticking it in a DB you should usemysql_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 toeval
then you've nothing to worry about - powerbuoy 2012-04-04 06:15