场景:我的PHP脚本需要10个POST
字符串才能工作。所有的值都需要用htmlspecialchars()
转义。所以脚本的第一行看起来像这样:
$var1 = htmlspecialchars($_POST['var1']);
$var2 = htmlspecialchars($_POST['var2']);
// And more. You get the point.
这是一些可以简化它的代码:
foreach($_POST as $key => $value){
$$key = htmlspecialchars($_POST[$value]);
}
我不确定用户输入的$$
。我猜有人可能会发送许多我不需要的POST请求,并以此阻止服务器。这现实吗?
foreach
代码将位于我的脚本的最顶部。所以它不能覆盖任何其他变量
与其盲目地处理$_POST
中的所有内容(尽管只是通过htmlspecialchars()
传递它们是相当无害的),不如使用可接受的密钥白名单:
// An array of $_POST keys that are acceptable
$whitelist = array('var1','var2','var3');
foreach($_POST as $key => $value) {
// Only handle $_POST keys you expect to receive...
if (in_array($key, $whitelist)) {
$$key = htmlspecialchars($_POST[$value]);
}
}
这避免了恶意用户向POST提交数百个值并消耗额外系统资源的可能性。
更新评论者是正确的。与$_POST
:
// Iterate over $whitelist and check for corresponding keys in $_POST
$missing_keys = array();
foreach($whitelist as $key) {
if (isset($_POST[$key])) {
$$key = htmlspecialchars($_POST[$key]);
}
else $missing_keys[] = $key;
}
echo "Missing keys: " . implode(",", $missing_keys);
不用担心他们会发送大量的_POST变量并"阻塞服务器"…这是由ini文件的post_max_size设置限制的,此外,_POST变量已经加载到内存中,所以最坏的情况下,您将(大致)使脚本的内存使用量增加一倍。如果你绝对确定你不会因为代码的位置而覆盖现有的变量,并且如果你确定你永远不会运行任何依赖于isset()触发器的代码,那么你应该是相当安全的。也就是说,将密钥列入白名单总是一个好主意。
对Michael Berkowski的公认答案的改进:
使用in_array()代替,使用白名单数组。
function sanitize($data) {
// fields to sanitize
$whitelist = array('title', 'category', 'tags', 'hovertext', 'content');
// loop over our data array
foreach ($data as $key => $val) { // loop over our data array
// if the current key is in our whitelist...
if (in_array($key, $whitelist)) {
// sanitize the value
$cleanVal = htmlspecialchars($val);
// replace the value in our data array
$data[$key] = $cleanVal;
}
}
// return our clean data array
return $data;
}