Jody Melbourne and David Jorm
In the first installment of this series we introduced the reader to web application security issues and stressed the significance of input validation. In the second installment, several categories of web application vulnerabilities were discussed and methods for locating these vulnerabilities were outlined. In this third and final article we will be investigating session security issues and cookies, buffer overflows and logic flaws, and providing links to further resources for the web application penetration tester.
Cookies are a mechanism for maintaining persistent data on the client side of a HTTP exchange. They are not part of the HTTP specification, but are a de-facto industry standard based on a specification issued by Netscape. Cookies involve the use of HTTP header responses to set values on the client side, and in client requests to provide these values back to the server side. The value is set using a 'Set-Cookie' header and returned using a 'Cookie' header. Take the following example of an exchange of cookies. The client requests a resource, and receives in the headers of the response:
Set-Cookie: PASSWORD=g0d; path=/; expires=Friday, 20-Jul-03 23:23:23 GMT
When the client requests a resource in path "/" on this server, it sends:
The browser is responsible for storing and retrieving cookie values. In both Netscape and Internet Explorer this is done using small temporary files; the security of these mechanisms is beyond the scope of this article, we are more concerned with the problems with cookies themselves.
Cookies are often used to authenticate users to an application. If the user's cookie is stolen or captured, an attacker can impersonate that user. There have been numerous browser vulnerabilities in the past that allow attackers to steal known cookies -- for more information on client-side cookie security, please refer to the cross-site scripting section in part two of this series.
Cookies should be treated by the developer as another form of user input and be subjected to the same validation routines. There have been numerous examples in the past of SQL injection and other vulnerabilities that are exploitable through manipulating cookie values. Refer to the PHPNuke admin cookie SQL injection, and Webware WebKit cookie overflow vulnerabilities.
Session Security and Session-IDs
Most modern web scripting languages include mechanisms to maintain session state. That is, the ability to establish variables such as access rights and localization settings which will apply to every interaction a user has with the web application until they terminate their session. This is achieved by the web server issuing a pseudo-unique string to the client known as a Session ID. Then the server associates elements of data with this ID, and the client provides the ID with each subsequent request made to the application. Both PHP and ASP have in-built support for sessions, with PHP providing them via GET variables and Cookies, and ASP via Cookies only.
The cookie method works in a similar manner, except the PHPSESSID (or Session-ID in the case of ASP) variable is persisted using a cookie rather than a GET variable. At a protocol level, this is just as dangerous as the GET method, as the Session ID can be logged, replayed or socially engineered. It is, however, obfuscated and more difficult to abuse as the Session ID is not embedded in the URL. The combination of cookies, sessions and a cross site scripting bug is just as dangerous, as the attacker need only post the document.cookie property to his logging application to extract the Session ID. Additionally, as a matter of convenience for the user, Session IDs are frequently set using cookies with either no expiry or a virtually infinite expiry date, such as a year from the present. This means that the cookie will always exist at the client side, and the window of opportunity will be indefinitely replayable as the cookie has no expiry date.
There are also many, albeit less common, forms of user session management. One technique is to embed the Session ID string in an tag with a