PHP表单输入过滤


PHP Form Input Filtering

我是一个PHP新手,我在一个基本的表单验证脚本工作。我理解出于安全原因,输入过滤和输出转义都是至关重要的。我的问题是,我在下面写的代码是否足够安全?先澄清一下。

  1. 我知道消毒和验证是有区别的。在下面的示例字段中,该字段是纯文本,因此我所需要做的就是对其进行清理。
  2. $clean['myfield']是我要发送给MySQL数据库的值。我正在使用准备语句为我的数据库交互。
  3. $html['myfield']是我发送回客户端的值,以便当他/她提交具有无效/不完整数据的表单时,具有数据的已处理字段将被重新填充,因此他们不必从头开始键入所有内容。

下面是(稍微清理过的)代码:

$clean = array();
$html = array();
$_POST['fname'] = filter_var($_POST['fname'], FILTER_SANITIZE_STRING);
$clean['fname'] = $_POST['fname'];
$html['fname'] = htmlentities($clean['fname'], ENT_QUOTES, 'UTF-8');
if ($_POST['fname'] == "") {
    $formerrors .= 'Please enter a valid first name.<br/><br/>';
}
else {
    $formerrors .= 'Name is valid!<br/><br/>';
}

谢谢你的帮助!

~ Jared

我理解出于安全原因输入过滤和输出转义都是至关重要的。

我宁愿说,出于安全和正确性的原因,输出转义是至关重要的,而输入过滤对于深度防御和强制执行特定的应用程序规则是潜在的有用措施。

输入过滤步骤和输出转义步骤必须是单独的问题,不能合并为一个步骤,尤其是因为有许多不同类型的输出转义,并且必须为每个输出上下文选择正确的转义(例如页面中的html转义、url转义以创建链接、sql转义等等)。

不幸的是,PHP传统上在这些问题上非常模糊,因此提供了一堆混合消息函数,可能会误导您。

在下面的示例字段中,该字段是纯文本,因此我所需要做的就是对其进行清理。

是的。唉,FILTER_SANITIZE_STRING在任何方面都不是一种理智的消毒剂。它完全删除了一些内容(strip_tags,这本身是高度不敏感的),同时html转义其他内容。eg引号变成&#34;。这是一派胡言。

相反,对于输入清理,请查看:

  • 检查它是否为您正在使用的编码的有效字符串(希望是UTF-8;

  • 删除控制字符,U+ 0000-U +001F和U+ 007F-U +009F。

  • 只允许换行符通过多行文本字段;
  • 删除不适合在标记中使用的字符;

  • 对于内容模型比任意文本字符串更具体的数据,逐字段验证输入是否符合应用程序需求。虽然您的转义应该正确处理<字符,但在没有意义的字段中尽早摆脱它可能是一个好主意。

对于输出转义步骤,我通常更喜欢htmlspecialchars()而不是htmlentities(),尽管正确使用UTF-8参数可以阻止后者以通常的方式中断。

根据您想要保护的内容,您调用的过滤器可能过于活跃(请参阅注释)。注射方面,你应该是安全的,因为你正在使用准备语句(见这个答案)

在设计说明中,您可能希望先进行筛选,然后检查空值。这样可以缩短代码;)

我理解输入过滤…对于安全来说是至关重要的。

这是一个错误的陈述。
虽然它在某些情况下可能是正确的,但在这种普遍化的形式下,它只能带来虚假的安全感。

我要做的就是消毒。

不存在像"一般消毒"这样的东西。你必须了解每个特定的情况以及它的局限性。例如,对于数据库,您需要使用几种不同的清理技术,而不是一种。而文件名则是完全不同的。

我正在使用预处理语句进行数据库交互。

因此,您根本不应该触摸数据。就这样吧。

下面是(稍微清理过的)代码:

你的代码中似乎有一些多余的东西。
您要清理HTML数据两次,而您可能根本不需要它。由于某些原因,你在成功时抛出了一个错误。

我宁愿这样做

$formerrors = '';
if ($_POST['fname'] == "") {
    $formerrors .= 'Please enter a valid first name.<br/><br/>';
}
if (!$formerrors) {
  $html = array();
  foreach ($_POST as $key => $val) {
    $html[$key] = htmlspecialchars($val,ENT_QUOTES);
  }
}