PHP表单输入过滤

时间:2012-01-03 23:06:42

标签: php forms security validation

我是一名PHP新手,正在研究基本的表单验证脚本。我知道输入过滤和输出转义对于安全性原因都至关重要。我的问题是我下面编写的代码是否足够安全?首先是一些澄清说明。

  1. 我知道清理和验证之间存在差异。在下面的示例字段中,该字段是纯文本,因此我需要做的就是清理它。
  2. $ clean ['myfield']是我发送给MySQL数据库的值。我正在使用预准备语句进行数据库交互。
  3. $ html ['myfield']是我发送回客户端的价值,这样当他/她提交包含无效/不完整数据的表单时,包含数据的已清理字段将被重新填充,因此他们不会我必须从头开始输入所有内容。
  4. 这是(略微清理过的)代码:

    $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/>';
    }
    

    感谢您的帮助!

    〜贾里德

3 个答案:

答案 0 :(得分:5)

  

据我所知,出于安全原因,输入过滤和输出转义都很重要。

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

输入过滤步骤和输出转义步骤必然是单独的关注点,并且不能组合成一个步骤,尤其是因为有许多不同类型的输出转义,并且必须为每个输出上下文选择正确的输出(例如,页面中的HTML转义,URL转义以进行链接,SQL转义等等。

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

  

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

是。唉,FILTER_SANITIZE_STRING绝不是一个理智的杀菌者。它完全删除了一些内容(strip_tags,这本身就非常不合理),同时HTML转义其他内容。例如,引号变为&#34;。这是胡说八道。

相反,对于输入消毒,请查看:

  • 检查它是您正在使用的编码的有效字符串(希望是UTF-8;请参阅例如this regex);

  • 删除控制字符,U + 0000-U + 001F和U + 007F-U + 009F。仅在故意的多行文本字段上允许换行;

  • 删除not suitable for use in markup;

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

对于输出转义步骤,我通常更喜欢htmlspecialchars()htmlentities(),尽管正确使用UTF-8参数可以阻止后一个函数以通常的方式打破。< / p>

答案 1 :(得分:1)

根据您要保护的内容,您调用的过滤器可能是overactive(请参阅注释)。注射方式你应该是安全的,因为你正在使用预备语句(见this answer

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

答案 2 :(得分:0)

  

我理解输入过滤......对于安全原因至关重要。

这是错误的陈述 虽然在某些情况下它是正确的,但在这种普遍的形式下,它可以做到没有好处,但却有错误的安全感。

  

我需要做的就是消毒它。

没有“一般消毒”这样的事情。您必须了解每个特定情况及其局限性。例如,对于数据库,您需要使用多种不同的清理技术,而不是一种。而对于文件名,它将完全不同。

  

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

因此,您根本不应该触摸数据。请保持原样。

  

这是(略微清理过的)代码:

您的代码似乎有些过分 您正在清理两次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);
  }
}