将超全局 $_POST 直接写入数据库是否明智


Is it wise to write superglobal $_POST directly to a database?

我想要一个适用于不同形式的提交代码,例如:

<?php 
 $type = $_GET['type'];
 if(isset($_SESSION['id']))
  handle_form();
 else 
  include 'form_'.$type.'.php'; // different fields based upon type
?>

所以我想知道遍历超全局 $_POST 将所有键和值写入数据库是否明智。像这样:

<?php 
 function handle_form() {
 $query = "";
 foreach($_POST as $key => $value) {
  $query .= mysql_real_escape_string($key)."='".mysql_real_escape_string($value)."' AND ";
 }
 mysql_query("UPDATE ".$_POST['type']." SET ".substr($query,0,-4)."WHERE `id` = $_SESSION['id']");
 }
?>

或者这是一种非常不安全的表单处理方法,是否最好硬编码相应"form_type.php"中的所有字段?

这是一个非常糟糕的主意,因为这样任何与列不对应的额外 POST 字段都会破坏查询。您自己的代码使用 $_POST['type'] 来确定要更新的表,除非您事先取消设置,否则该表也会中断。

此外,您不会对实际发送到数据库的数据进行任何验证。将您自己的姓名/权限更改为管理员?确定。将其他用户的电子邮件更改为您自己的电子邮件?继续。使您的帐户余额+100,000$?没关系。将产品标记为"价格 1 美元"?是的。

拥有某种活动记录会更聪明。如果你正在编写一个更大的应用程序,看看像Yii或Cake PHP这样的框架,它们内置了这样的功能。


除此之外:请停止使用古老的 mysql_* 函数编写新代码。它们不再被维护,社区已经开始弃用过程。相反,您应该了解预准备语句并使用PDO或MySQLi。如果你想学习,这里有一个非常好的PDO相关教程。

来自不受信任的外部源的所有内容都不安全地插入到数据库或其他任何地方,因为存在代码注入的风险。对于数据库,您将面临SQL注入的风险。您必须清理输入。这适用于任何超全局变量以及您无法控制的任何其他数据,例如 Web 服务。

使用mysql_real_escape_string转义数据是您需要做的最低限度,但它并不能保护您免受所有可能的注入攻击。它是纯粹的语法,无法检测到对语法正确的数据值的篡改。

除此之外,你不应该再使用ext/mysql了。它已过时,将被弃用。使用 ext/mysqli 或 PDO 并使用预准备语句。

这是一场潜在的噩梦。永远不要信任你的用户。

每个 $_POST 参数应检查为:

  • 它是接受参数白名单的一部分吗?
  • 它有正确的数据类型或值范围吗?

然后,请使用预准备语句,而不是普通的 mysql_query(( 调用。