Incompatible Parameter Parsing ============================== Sverre H. Huseby, 2005-04-29 URL: http://shh.thathost.com/text/incompatible-parameter-parsing.txt Dangerous attacks may be possible if different parts of an application use incompatible methods when extracting incoming parameters. This is probably not news to everyone, but since I can't remember having seen anything about it, and since I know there are people out there who haven't thought very hard about it before, I made this little write-up. When a user visits a web site through a URI that looks like this: http://www.example.com/something?foo=bar the web server at www.example.com will receive a GET request in which the Request-Line looks like this: GET /something?foo=bar HTTP/1.0 By tradition, the part following the question mark up to the HTTP-Version identifier, i.e. "foo=bar" in the above case, is called the QUERY_STRING. The web application framework in use will extract parameters from what QUERY_STRING, typically splitting first on ampersands, and then on equals signs. If you're using some Java Servlet-based framework, it's quite clear that the return value from calling request.getParameter("foo") will be "bar". But what is not equally clear, is what will be returned if the original request contains several "foo" parameters, like this: http://www.example.com/something?foo=bar&foo=gazonk Will it return "bar", or will it return "gazonk"? Unfortunately, the Java Servlet API isn't very clear. Other platform APIs typically do not address this issue in detail either, so in general, it is implementation dependant. Now what if the request was like this: http://www.example.com/something?foo%20=bar Note the embedded space character (%20) following "foo". Will it be trimmed away, so that this is actually a plain, three-letter "foo", or will the parameter be named "foo " with a space at the end? I don't know, at least not without experimenting, and the experiments will only reveal how it is implemented in the particular version of the particular framework I test for. Now why all this fuzz about how the framework parses incoming parameters (both from GET and POST requests and even cookies)? A couple of times the last six months I've seen developers inserting "security-enhancing" front ends between the web server (e.g. Apache, Microsoft IIS) and the web application framework (e.g. Java Servlets, something.NET), and in both cases it was possible to bypass the security front end because the parameter parsing of the front end was incompatible with the parameter parsing of the web application framework. I'll give you the two examples, albeit slightly modified from how they actually appeared in order to protect my clients. In the first example, the client had created an ISAPI filter for Microsoft IIS. This filter did sanity checking of selected parameters, in order to prevent exploits in the "actual", .NET-based web application logic. If illegal input for the selected fields were detected, the filter would refuse to pass the request on. Unfortunately, the filter's extraction of parameters was a tad naive. When the filter was looking for a parameter named "foo", it would scan the entire QUERY_STRING for "?foo" and "&foo", and if found, would skip the next character in the belief that it was an equals sign. As the web application behind it would not skip the equals sign, it was perfectly possible to pass a highly invalid "foo" like this: ?fooab&foo=INVALID-VALUE The ISAPI filter would think that the value of "foo" was "b", which is OK, and leave it to the main application logic to crash and burn on the "INVALID-INPUT" value. The other application had pushed user authentication to some front end filter code. As part of the authentication logic, the filter would look for an incoming "user" parameter, which contained the name of the user to authenticate. If authentication was OK, the request would go on to the main application logic, otherwise it would be terminated. The main application logic would use the same incoming "user" parameter to do authorization tests, believing that the user was authenticated by the front end. The fun thing with this web site was that the authenticating front end searched for the "user" parameter by looking for the first occurrence of the substring "user=", and therefore also would match on a parameter named e.g. "bazuser". An already authenticated user could thus impersonate another user by passing bazuser=AUTHENTICATED-USER&user=IMPERSONATED-USER The front end would look up "bazuser" and decide that he was OK, while the application itself would look up "user" and assume this user was already authenticated. How to avoid similar problems? It depends, I guess. Before adding a front end, consider if it is really needed. If the same functionality could be put inside the web application framework, then put it there. If not, make sure your front end mimics the parameter parsing of the web application framework as closely as possible, and recheck that it still does whenever the framework is updated. (I was just (2005-04-30) informed that Ivan Ristic has written about similar issues in his blog recently: http://www.modsecurity.org/blog/archives/000053.html )