不,这是没有必要的。但是,请继续阅读。
输入清理是一个可怕的术语,它假装您可以对数据挥动魔杖并使其成为“安全数据”。问题在于,当数据被不同的软件解释时,“安全”的定义会发生变化。
可以安全地嵌入到 SQL 查询中的数据可能不安全地嵌入到 HTML 中。或 JSON。或外壳命令。或 CSV。并且剥离(或彻底拒绝)值以便它们可以安全地嵌入所有这些上下文(以及许多其他上下文)中,限制性太强。
那么我们应该怎么做呢?确保数据永远不会造成损害。
实现这一点的最佳方法是首先避免解释数据。参数化 SQL 查询就是一个很好的例子;参数永远不会被解释为 SQL,它们只是作为数据放入数据库中。
对于许多其他情况,数据仍然需要以其他格式嵌入,例如 HTML。在这种情况下,该特定语言的数据应在嵌入时进行转义。因此,为了防止 XSS,数据在查看时进行了 HTML 转义。不是在输入时。这同样适用于其他嵌入情况。
那么,我们应该直接将我们得到的任何东西传递给数据库吗?
或许。这取决于。
您肯定可以检查有关用户输入的一些事情,但这高度依赖于上下文。因为 sanitization 定义不明确且被误用,所以我更喜欢称它为validation。
- 例如,如果某个字段应该是整数,您当然可以验证该字段以确保它包含整数(或者可能为 NULL)。
- 您当然可以对电子邮件字段进行一些验证(尽管有些人认为除了检查 a 的存在之外您无能为力
@
,他们有一个很好的观点)。
- 您可以要求评论具有最小和最大长度。
- 您可能应该验证任何字符串仅包含对其编码的有效字符(例如,没有无效的 UTF-8 序列)。
- 如果这对您的用户群有意义,您可以将用户名限制为某些字符。
- 当然,密码的最小长度非常普遍。
如您所见,这些检查非常依赖于上下文。所有这些都是为了帮助增加您最终获得有意义数据的几率。它们不是为了保护您的应用程序免受恶意输入(SQL 注入、XSS、命令注入等),因为这不是这样做的地方。
用户应该可以自由打字'; DROP TABLE users; --
,而他们的帖子不会被拒绝或修改为\'; DROP TABLE users; --
. 请注意,我可以在 sec.SE 上包含此类“恶意”内容!
所以,回答你原来的问题:
...以某种方式清理输入是否仍然有必要和/或与安全相关?
不它不是。但是请在输出之前正确地转义需要的数据。并在适用的情况下考虑验证。
我想到了良性但设计不那么好的第 3 方工具(可能是管理员自己编写的脚本,或者是非技术人员制作的一些花哨的 CrystalReports)试图从我们的数据库中使用未经清理的数据。
然后在输出到这些工具之前转义或过滤数据,但不要破坏数据库中的数据。
但实际上,这些脚本应该被修复,或者考虑到安全性而重写。
(MySQL似乎对Emojis有问题)
有点离题,但看看utfmb4
MySQL的字符集;)