|
防卫不同种类的输入攻击可能需要对用户的输入执行不同的验证检查,这些验证检查是不兼容的。例如阻止跨站脚本攻击可以要求HTML加密“>”为">";而阻止命令注入攻击(command inject)可能需要阻止包含&和;字符的输入。试图在应用程序的外部边界同时阻止所有种类的攻击有时是不可能的。
如果对用户的输入没有进行仔细的多级检查的话,攻击者构建的输入就可能会得逞。当一个应用程序试图通过删除或加密特定的字符或表达式来过滤用户的输入的话,这种情况就可能会出现。例如,一个应用程序可能试图从用户提交的数据中通过去掉表达式<script>来防止某些跨站脚本攻击,那么攻击者可能通过输入<scr<script>ipt>来绕过这个过滤。这是因为这个过滤没有被递归地使用,当<scr<script>ipt>中间的<script>被去掉后,剩下的还是<script>。
类似的情况就是,攻击者可以利用多步检查的顺序来绕过这个过滤。例如如果一个应用程序第一是递归地去掉<script>表达式,然后是去掉"符号的话,那么<scr"ipt>就可以成功绕过这个过滤。
另一个问题是在用户输入的数据被解密时会发生的。从用户浏览器过来的数据会是以不同方法加密了的数据,那么就需要对这些数据进行恢复,也就是转换或解密为通常的字符。如果解密是在输入过滤之后,那么攻击者就可以通过加密来绕过这个检查机制。例如,如果一个应用程序通过删除用户输入数据中"号来防止某些SQL注入攻击的话,由于过滤先于恢复,那么攻击者可以使用"号的URL加密形式%27来绕过这个检查机制。同理,如果检查机制也会去掉%27话,只要没有递归处理,那么%%2727就能够得逞。
有时候避免多步检查和恢复中存在的问题是比较困难的。不存在单一的方案能够解决这些问题。有些情况下,递归地处理一个有问题的字符可能会
导致死循环,通常,这只能在所执行的检查类型上来根据情况处理,情况允许的话,更好的方法就是简单地拒绝某些类型的恶意输入。
|