过滤用户输入 - 需要澄清

时间:2010-09-05 03:28:54

标签: php validation filter sanitization

我想澄清用PHP过滤用户输入的正确方法是什么。例如,我有一个用户输入信息的Web表单。提交时,表格中的数据将被输入数据库。

我的理解是你不想清理进入数据库的数据,除了逃避它如mysql_escape_string之外,你想要在前端用htmlentities或htmlspecialchars这样的东西清理它时要清理它。但是,如果您希望在提交表单时可以验证/过滤用户输入,以确保数据格式正确,例如,如果字段是用于电子邮件地址,则要验证其是否具有正确的电子邮件格式。这是对的吗?

我的下一个问题是,当您在网络表单中重新显示数据时,如何处理数据?让我们说,允许用户在填写完信息并将信息添加到数据库后编辑该表单中的信息。然后他们返回并查看他们最初输入的字段中的数据,您是否必须清理数据以便在表单字段中正确显示?例如,有一个名为My Title的字段,输入My title的人是“Manager”。您可以看到管理器周围的引用,当您将其显示在表单字段中时,它会因为引号而中断:

<input type="text" name="title" value="My title is "Manager"">

所以,你不必像htmlentities那样将引文转换为html实体吗?否则,该字段的值看起来像我的标题

希望这是有道理的。

1 个答案:

答案 0 :(得分:2)

没有任何内容表明您无法在插入数据库之前清理数据。毕竟,如果您的脚本/网站/公司有关于表单字段中可接受的内容的特定策略,则最好在保存之前删除任何不允许的内容。这样,您只需在数据插入/更新之前清理一次,而不是每次都检索数据。

如果您允许HTML实体用于(例如)重音字符,而不允许使用HTML标记,那么您还必须同时检查无效实体(&foobar;?)和HTML标记。由于您不允许它们,所以不要费心存储它们。如果您需要有效的电子邮件地址,请检查它是否符合RFC 5322标准,并且只有在用户输入正确数据后才存储它。 (该电子邮件地址是否确实存在是另一回事。)

现在,让我们直截了当。清理和逃避之间存在差异。消毒意味着从字面上清理 - 你正在从数据中删除任何你不想要的东西。您可以静默删除它,或向用户显示错误并告诉他们修复它。另一方面,转义只是一种编码数据的方法,因此它可以正确显示。

使用My title is "Manager"字符串,您无需对其进行消毒,因为没有任何错误或令人反感的内容。你需要做的是逃避它,至少htmlspecialchars(),以便嵌入的双引号不会“破坏”你的形式。如果您逐字嵌入,大多数浏览器会将其视为value="My title is"和一些虚假属性/垃圾Manager""。所以,你通过htmlspecialchars运行它并结束My title is &quot;Manager&quot;,它完美地嵌入value="",没有任何问题。没有消毒,只需要正确的编码。

现在,当提交该表单时,您必须再次进行清理/验证,因为数据已经掌握在潜在恶意用户手中,并且数据可能已更改为My title is <script>document.location='http://attacksite.com';</script>pwn me

基本上,工作流程应为:

  1. 向用户提供表格
  2. 提交数据。
  3. 清理数据
  4. 如果表单未正确填写,则显示错误并转到1)
  5. sql查询的转义数据
  6. 插入数据库
  7. 然后再

    1. 从数据库中检索数据
    2. 适当的转义/编码,但会显示
    3. 显示数据。如果数据进入表格,请像以前一样做1-6。