输出或输入过滤?
我经常看到人们写“过滤你输入”,“消毒你的输入”,不信任用户数据,但我只同意最后一个,我认为相信任何外部数据都是个坏主意,即使它是内部相对于系统。
输入过滤: 我看到的最常见。 获取表单发布数据或任何其他外部信息源并在保存时定义一些边界,例如确保文本是文本,数字是数字,sql是有效的sql,html是有效的html并且它不包含有害的标记,然后将“安全”数据保存在数据库中。
但是在获取数据时,您只需使用数据库中的原始数据。
在我个人看来,数据永远不会真正安全。 虽然听起来很简单,但只需过滤从表单和网址获得的所有内容,实际上它比这更难,对一种语言而言可能是安全的而不是另一种语言。
输出过滤: 当这样做时,我将原始未更改的数据(无论它是什么)保存到数据库中,然后在访问数据时过滤掉有问题的代码,这有其自身的优点: 这在html和服务器端脚本之间添加了一个层。 我认为是各种数据访问分离。
现在根据上下文过滤数据,例如,我可以将数据库中的数据作为普通转义文本显示在html文档中,或者作为html或任何地方显示。
这里的缺点是你不能忘记添加比输入过滤更难的过滤,并且在提供数据时它会使用更多的CPU。
这并不意味着您不需要进行验证检查,您仍然可以,只是您不保存过滤后的数据,验证它并在数据以某种方式提供给用户错误消息无效。
因此,不应使用“过滤您的输入”,而应该是“验证您的输入,过滤您的输出”。
我应该使用“输入验证和过滤”或“输入验证和输出过滤”吗?
答案 0 :(得分:4)
输入和输出没有通用的“过滤”。
验证输入,转义输出。你如何做到这一点取决于具体情况。
验证是关于确保输入在合理范围内,例如字符串的长度,美元金额的数字或正在更新的记录由执行更新的用户拥有。这是为了保持数据的逻辑一致性,并防止人们做出诸如将他们购买的产品的价格归零或删除他们无法访问的记录这样的事情。它与“过滤”或转义输入中的特定字符无关。
转义是一个上下文的问题,只有当您使用注入某些字符可能会中毒的数据时才会真正有意义。转义发送到浏览器的数据中的HTML字符。转义发送到数据库的数据中的SQL字符。在JavaScript <script>
标记内写入数据时转义引号。只是要意识到你正在处理的数据将如何被你传递给它的系统解释并相应地逃脱。
答案 1 :(得分:0)
最好的解决方案是过滤两者。只做一个就会让你更有可能错过一个案例,并且可以让你接受其他类型的攻击。</ p>
如果您只进行输入过滤,攻击者可以找到绕过输入并导致漏洞的方法。这可能是有权访问您的数据库的人手动输入数据,可能是攻击者通过FTP或其他未经检查的通道上传文件,或许多其他方法。
如果您只进行输出过滤,则可以让自己接受SQL注入和其他服务器端攻击。
最好的方法是过滤输入和输出。它可能会导致更多负载,但会大大降低攻击者发现漏洞的风险。
答案 2 :(得分:-1)
对我来说听起来像语义。无论哪种方式,重要的是要记住确保坏数据不会进入系统。
执行输出过滤而不是输入过滤是要求SQL注入。