很多web应用程序防火墙有一个困难的工作——在对应用程序和商业逻辑完全不了解的情况下,搞清经过的数据的意思。他们提供的保护来源于在外部拥有的一个独立安全层。因为数据确认作了两次,可以在不触动应用程序的前提下增加安全性。但是,在某些情况下,每件事情都作两次会带来问题。在通信协议没有很好定义的地方,或者在设备或应用程序在做一些规范中没有定义的事情。
最糟糕的违规者是cookie规范。(实际上是所有这4个定义:http://wp.netscape.com/newsref/std/cookie_spec.html, http://www.ietf.org/rfc/rfc2109.txt,
http://www.ietf.org/rfc/rfc2964.txt,http://www.ietf.org/rfc/rfc2965.txt)。因为很多真实的生活可能发生的情况,在这个规范中没有定义——留给程序员去做任何他们认为适宜的事情。大多数情况这不是问题,如果cookie是结构良好的话——事实上多数情况下是的。问题不明显还因为多数应用程序解析的cookie都是这些应用程序自己发送的。如果你从web应用程序防火墙的角度观察,当一个确定的对手试图突破它的时候,这就是问题了。
我会用一个例子来解释。
ModSecurity的1.8.x分支,直至1.8.6(我在1.8.7中做了改进)使用了一个cookie解析器。当我写这个解析器的时候,我觉得它真的很好,因为它能够处理v0和v1的cookie。但是,我犯了一个错误,没有象一个攻击者那样去思考。正如Stefan Esser向我指出的,在v0和v2之间的格式差异可能被利用,使得一个v1的解析器看到一个cookie,但是一个v0的解析器看到更多。就像这样:
Cookie:
innocent=”; nasty=payload; third=”
V0的解析器不识别双引号。它只寻找分号然后分割报头。一个这样的解析器看到的多个cookie:“innocent”,“nasty”,“third”。另一方面,V1的解析器只看到一个cookie——“innocent”。
阻抗不匹配是如何影响web应用程序防火墙的用户和开发者的呢?它当然会让生活变得复杂,但是这没关系——这是游戏的一部分。开发者必须合并比较好和比较快的解析程序。例如,ModSecurity
1.8.7包含两个cookie解析器。用户可以选择任一使用(默认使用v0的解析器)。但是因为不能自动化,这样的改进只是使防火墙更加复杂——又多了一件需要用户思考和配置的东西。
另一个方面,如果不想考虑cookie解析器的问题,用户总可以后退回去使用HTTP中那些定义的更好的部分。例如,用户可以使用HTTP_Cookie来定位整个cookie报头,而不是用Cookie_innocent来定位一个单独的cookie。其他变量,比如ARGS,可以看到全部的变量,不管对手多么努力的掩饰他们。