这个问题最初是在此处的评论中提出的。
如果在打印任何用户提供的数据之前使用参数化查询和htmlspecialchars() ,是否仍然需要filter_input()?
这对我来说似乎没有必要,但我一直被告知要“过滤输入,转义输出”。那么,除了数据库(或其他形式的存储)之外,是否需要过滤输入的数据?
这个问题最初是在此处的评论中提出的。
如果在打印任何用户提供的数据之前使用参数化查询和htmlspecialchars() ,是否仍然需要filter_input()?
这对我来说似乎没有必要,但我一直被告知要“过滤输入,转义输出”。那么,除了数据库(或其他形式的存储)之外,是否需要过滤输入的数据?
好吧,会有不同的意见。
我的看法是你应该总是使用它(或者,filter
一般的扩展)。这至少有3个原因:
清理输入是您应该始终做的事情。由于该功能为您提供了此功能,因此实际上没有理由寻找其他方法来清理输入。由于它是一个扩展,过滤器也将比那里的大多数 PHP 解决方案更快并且最有可能更安全,这当然不会受到伤害。唯一的例外是如果您需要更专业的过滤器。即使这样,您也应该使用FILTER_UNSAFE_RAW
过滤器获取值(参见#3)。
filter
扩展中有很多好东西。它可以节省您编写清理和验证代码的时间。当然,它并没有涵盖每一种情况,但已经足够让您可以更专注于特定的过滤/验证代码。
在调试/审核代码时使用该功能非常有用。使用该功能时,您确切知道输入将是什么。例如,如果您使用FILTER_SANITIZE_NUMBER_INT
过滤器,那么您可以确定输入将是一个数字——没有 SQL 注入、没有 HTML 或 Javascript 代码等。另一方面,如果您使用类似的东西,FILTER_UNSAFE_RAW
那么您就知道它应谨慎对待,而且很容易引起安全问题。
正如 Sverri M. Olsen 所说,对此有不同的看法。
我非常同意Filter Input, Escape Output的哲学。
如果在打印任何用户提供的数据之前使用参数化查询和 htmlspecialchars(),是否仍然需要 filter_input()?
简短回答: IMO,不。这不是必需的,但在某些情况下可能很有用。
该filter_input
函数有许多有用的过滤器,我确实使用了其中的一些(即 FILTER_VALIDATE_EMAIL)。验证过滤器对于验证输入很有用。但是,IMO,那些转换数据的应该只用于输出。
有些人鼓励逃避输入。实际上,filter_input手册页上给出的示例似乎也鼓励了这一点。
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
唯一的例子是escaping。结合函数名称(filter_input )似乎表明转义输入是一种好习惯。转义是必要的,但是,IMO,应该在输出之前完成,而不是在输入时。至少返回值被存储在适当命名的变量中。
我强烈不同意转义input。我已经遇到过过早转换数据是一个问题的现实世界情况。
例如,Google Analytics 处理输入的方式会导致我的编码 & 符号 (%26) 在查询参数被排除之前被解码。结果是我的 URL 中实际上不存在的查询参数的统计信息。请参阅我关于这个仍未解决的问题的问题。
您可能还想阅读Why escape-on-input is a bad idea。这里有一些我同意的摘录,以防文章消失[强调原文]。
[...] 输入时转义是错误的[...] 这是一个分层违规——它将输出格式问题混合到输入处理中。分层违规使您的代码更难理解和维护,因为您必须考虑其他层,而不是让每个组件和层各司其职。
和
默认情况下,您已损坏数据。系统 [...] 现在对输入的数据撒谎。
和
对输入进行转义不仅无法处理多个输出的问题,而且实际上会使您的数据对于许多输出不正确。
和
PHP 曾经有一个称为魔术引号的功能。这是一个输入时转义功能,[...] 导致了各种问题。[...] 根据 Lerdorf 的说法,更新的 PHP 'filter' 扩展是“magic_quotes done right”。但它仍然受到这里描述的几乎所有问题的困扰。
那么过滤器扩展如何比魔术引号更好(除了它有许多不同的过滤器的事实)?过滤器会导致许多与魔术引号相同的问题。
以下是我使用的编码约定:
术语
出于我的目的,这就是我定义上面使用的术语的方式。
概括
一般来说(可能有一些例外),我建议如下: