何时过滤/清理数据:在数据库插入之前或显示之前?

Jus*_*ton 21 html php filter sanitize

当我准备解决输入数据过滤和消毒问题时,我很好奇是否有最佳(或最常用)的做法?在将数据插入数据库之前过滤/清理数据(HTML,JavaScript等)是否更好?还是应该在准备数据以便在HTML中显示时完成?

几点说明:

  • 我在PHP中这样做,但我怀疑这个问题的答案是语言不可知的.但是,如果您有任何特定于PHP的建议,请分享!
  • 这不是转义数据库插入数据的问题.我已经很好地处理了PDO.

谢谢!

jas*_*son 18

在显示用户提交的数据时,普遍接受的口号是"过滤输入,转义输出".

在进入数据库之前,我建议不要转义像html实体之类的东西,因为你永远不知道什么时候HTML不会成为你的显示媒体.此外,不同类型的情况需要不同类型的输出转义.例如,在Javascript中嵌入字符串需要与HTML中不同的转义.以前这样做可能会让自己陷入虚假的安全感.

因此,基本的经验法则是,在使用前进行消毒,特别是用于该用途; 不是先发制人.

(请注意,我不是在讨论转义SQL的输出,只是为了显示.请继续转义绑定SQL字符串的数据).


Ber*_*Ott 11

我喜欢以原始形式存储/存储数据.我只根据我使用它的位置来逃避/过滤数据.

  • 在网页上 - 编码所有HTML
  • 在sql上 - 杀死引号
  • 在网址上 - urlencoding
  • 在打印机上 - 编码转义命令
  • 什么都有 - 为那份工作编码


Pas*_*TIN 7

您应该关注至少两种类型的过滤/清理:

  • SQL
  • HTML

显然,第一个必须在将数据插入数据库之前/之后进行处理,以防止SQL注入.
但是你已经知道了,正如你所说,所以我不会再谈论它了.


另一方面,第二个是一个更有趣的问题:

  • 如果您的用户必须能够编辑他们的数据,那么将它们返回给他们是有趣的,就像他们最初输入数据一样; 这意味着您必须存储"非HTML-specialchars-escaped"版本.
  • 如果你想要显示一些HTML,你可能会使用像HTMLPurifier这样的东西:功能非常强大......但如果你必须在每个数据上运行它时可能需要一些太多的资源......

所以:

  • 如果你想显示一些HTML,使用繁重的工具来验证/过滤它,我会说你需要将已经过滤的/无论什么版本存储到数据库中,以免破坏服务器,每次数据都重新创建它被展示
    • 但你还需要存储"原始"版本(请参阅我之前说过的内容)
    • 在这种情况下,我可能会将两个版本存储到数据库中,即使它需要更多的地方......或者至少使用一些好的缓存机制,不要一遍又一遍地重新创建干净的版本.
  • 如果您不想显示任何HTML,您将使用htmlspecialchars或等效,这可能不是一个CPU吃的人......所以它可能没关系
    • 你仍然需要存储"原始"版本
    • 但是在输出数据时转义可能没问题.

BTW,第一个解决方案也很好,如果用户在输入数据时使用bbcode/markdown/wiki之类的东西,并且你用HTML呈现它......
至少,只要它显示的频率高于它的更新 - 并且特别是如果您不使用任何缓存来存储干净的HTML版本.


cha*_*aos 6

如果需要(例如,如果您没有使用为您处理的数据库交互层),请在将数据库放入数据库之前对其进行清理.在显示之前将其消毒以进行显示.

以目前不必要的引用形式存储东西只会导致太多问题.


小智 6

在将它们传递到需要逃脱的地方之前,我总是说要逃避它们.您的数据库不关心HTML,因此在存储到数据库之前转义HTML是不必要的.如果您希望输出HTML以外的内容,或者更改允许/禁止哪些标记,您可能需要先做一些工作.此外,在需要完成时,比在过程的早期阶段更容易记住进行转义.

值得注意的是,HTML转义字符串可能比原始输入长得多.如果我在注册表单中放入日语用户名,原始字符串可能只有4个Unicode字符,但HTML转义可能会将其转换为长字符串"〹𐤲䡈穩" .那么我的4个字符的用户名对于你的数据库字段来说太长了,并且存储为两个日文字符加上一半的转义代码,这也可能阻止我登录.

请注意,浏览器往往会在提交的表单本身中忽略某些非英语文本等内容,并且总会有智能手机在任何地方都使用日语用户名.所以,你可能想实际UNESCAPE存储之前的HTML.