我有点困惑。当我在谷歌上打字时,几乎所有的文章都建议使用Filter input, escape output.
。如果我一辈子都没有混淆转义和过滤这两个术语,那应该是相反的。
你会得到很多像一样的文章
$username = htmlentities(htmlspecialchars(strip_tags($_POST['username')));
并建议这样做。
我们不应该过滤输入。我们应该对其进行转义(以前我们使用mysql_real_
escape
_string进行转义,现在准备好的语句为我们处理它们。)我们应该将用户提交的数据插入数据库as-is
,而不使用htmlspecialchars
等函数对其进行更改。我们应该始终将原始输入保存在数据库中,因此输入过程中的htmlspecialchars
是错误的。HTML对数据库无害。我们应该过滤输出,这样恶意代码(html、js等)就不会在浏览器上运行。这被称为
XSS filtering
,而不是XSS escaping
。例如,Laravel 4上的{{{ $var }}}
被称为XSS filtering
,这应该始终用于用户提交的内容的输出。
如果语句Filter input escape output
是正确的,为什么它不是mysql_real_filter_string()
,并且防止XSS没有被调用为XSS escaping
?
此外,ircmaxell
曾经说过:
筛选不是为了防止安全漏洞,而是为了不在数据库中填充垃圾。如果你期待一个日期,在存储它之前,确保它至少看起来像一个日期
这被称为validation
,并且不能仅依赖于验证。(尤其是在旧版本的PHP上)您需要对输入进行转义和验证。筛选可能不用于安全漏洞,但可以进行转义。
好吧,这总结了我的困惑。有人能向我解释一下吗?
看起来我的困惑很简单。当我们开始使用echo
的时,我认为输出层就是那个层,比如视图层。
根据Anthony Ferrara的说法,输出是数据离开应用程序的那一层,输入是数据进入应用程序的这一层。
因此,Input
层不仅限于用户提供的内容,而且从配置文件读取、从文件系统读取、从第三方API检索数据等都被认为是Input
。
CCD_ 18不限于视图层上的CCD_ 19或CCD_。SQL queries
也算作output
,因为数据离开我们的应用程序并进入数据库的范围。因此,写入文件也算作输出,执行shell命令也算作输出。
所以基本上,查询数据库是Output
,而从数据库中检索结果是Input
。
当你这样想的时候,Filter input, escape output
听起来是正确的。如果其他人和我一样感到困惑,这真的很有道理。
首先:htmlentities
或htmlspecialchars
实际上不转义字符串,它们将特定字符转换为html实体!
-
首先,您应该接受用户输入,并删除伪/自动的"安全"类魔术引号。
if (get_magic_quotes_gpc()) { $lastname = stripslashes($_POST['lastname']); // ... }
这样就可以获得"纯"或原始用户输入。
-
那么过滤意味着例如不允许
fooBar
之类的内容作为电子邮件地址!if (!my_own_email_validity_check($_POST['email'])) die(); // maybe a bit extreme
-
之后转义要存储的用户输入(例如在数据库中)
$city = $mysqli->real_escape_string($city);
或者最好使用PDO,它"自动"完成:-)
-
但真正重要的部分是,当向用户显示数据库中的数据时,请确保您通过
htmlspecialchars()
运行所有数据,因为您无法确定其中的任何内容是否正常!!!
现在有其他观点认为,当你获得原始数据时,你应该立即运行htmlentities,但这让处理它变得可怕,而且不是推荐的方法。但这甚至可能取决于你在做什么,就像做很多事情一样。
所以总结一下,总的来说:
- 当存储时,您需要转义用户输入,这样您就可以安全地避免注入
- 当显示时,您需要转换存储的数据,以防XSS
编辑:命名也有很多不同,有时人们在逃离时称之为过滤,或者在净化时称其为一般的逃离,等等。所以不要被命名所混淆,只要了解发生了什么,你就会没事的;-)
编辑2: 回答您的问题:
它被称为"过滤器输入,转义输出",因为。。。
- 在这种情况下,过滤实际上意味着不允许数据库中出现"错误"数据。(比如第2点,电子邮件验证、邮政编码,这些都是你可以排除的。以后可能会打乱你的数据处理!)
- Escape输出是为了防止XSS->实际转换为html实体,所以这里是一个命名的例子
- 在"filter input,escape output"中,要么不考虑转义以防止SQL注入,要么甚至用"filtering"来概括它(正如您所说,这不是正确的术语(imho))
在我看来,问题是命名不一致。
过滤输入和转义输出以防止存储不可信的、注入的坏数据,同时防止跨站点脚本(XSS)http://shiflett.org/blog/2005/filter-input-escape-outputhttp://shiflett.org/blog/2005/more-on-filtering-input-and-escaping-output
过滤输入并不意味着不通过转义来净化SQL插入。这只是一个朗朗上口、简洁明了的最佳实践,要记住认真负责。Chris Shiflett并没有说你永远不会逃避输入或过滤输出。