我的表单中有这个选择输入,我想通过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>
通过将选择元素的名称设置为"水果[]",这就起作用了:
// |$fruits| is an array
$fruits = $_POST['fruits']
然而,我担心从表单中清除数据。将post数据输入数组听起来不安全。例如,如果有人通过Firebug将select元素更改为文本输入元素,并将恶意代码输入到我的程序中,该怎么办?我从不给htmlspecialchars
打电话。
我的安全顾虑有效吗?为什么?
它们确实有效,如果数据来自用户输入,则需要首先对其进行清理。
在这种情况下,用户可以很容易地破坏HTML,甚至更糟的是,注入一些恶意的XSS攻击。
您需要清除这些值,在这种情况下htmlspecialchars
就足够了。
无论如何,我知道您在用用户输入的选项填充HTML选择标记,但事实并非如此。PHP只接受POST数据中的字符串或数组,因此您需要确保传入的数据与您想要使用的数据兼容。一种可能的解决方案是将提交的值列为白名单,像array_intersect
这样的函数在这里可能很有用,例如:
$allowed_fruits = array('Apple', 'Banana', 'Cherry');
$fruits = array_intersect($allowed_fruits, $_POST['fruits']);
这样,如果用户提交"Strawberries",它将在$fruits
数组中被忽略。
您可能还想确保数组不是多维的,比如:
if (count($_POST['fruits']) != count($_POST['fruits'], COUNT_RECURSIVE))
{
// array is multidimensional, do not process
}
当然,这取决于您对数据的使用,但白名单方法始终是最安全的。
在将用户输入发送到数据库、html输出、日志或其他位置之前,您的代码应该验证用户输入是否为预期格式(isset
、is_array
…)和是否正确转义。从根本上讲,这里用户输入的字符串和用户输入的数组之间几乎没有区别。
使用mysql_real_escape_string
(甚至更好的PDO
)处理数据库,使用htmlspecialchars
处理HTML输出。
这是获取值的正确方法,不过,您应该担心。您可以按照建议的方式接收值,然后使用适当的清理方法:用于显示的htmlspecialchar、用于插入数据库的mysql_escape等。您需要为数组中的每个元素执行此操作,但只能在您要使用它的时候执行。