PHP -自动处理每个$_POST变量可能是一个安全问题


PHP - Could automatically processing every $_POST variable be a security issue?

场景:我的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;
}