这是从PHP中的select元素访问选项的可靠方法吗


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

我的表单中有这个选择输入,我想通过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输出、日志或其他位置之前,您的代码应该验证用户输入是否为预期格式(issetis_array…)是否正确转义。从根本上讲,这里用户输入的字符串和用户输入的数组之间几乎没有区别。

使用mysql_real_escape_string(甚至更好的PDO)处理数据库,使用htmlspecialchars处理HTML输出。

这是获取值的正确方法,不过,您应该担心。您可以按照建议的方式接收值,然后使用适当的清理方法:用于显示的htmlspecialchar、用于插入数据库的mysql_escape等。您需要为数组中的每个元素执行此操作,但只能在您要使用它的时候执行。