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