This is the second post in our Building Secure Web Apps series.
Traditional single-cookie session management leaves Web applications vulnerable to Cross-Site Request Forgery (CSRF) attacks. CSRF attacks exploit the fact that browsers will send associated cookies with any request, regardless of why the request is being sent, and that servers will accept session tokens in the Cookie header. Attackers can cause requests to be sent with full session credentials from attacker-controlled Web pages, and depending on the nature of the targeted Web application, that can be a very serious problem.
Web application developers can't do anything about the browser behavior, but they can take advantage of some browser features to provide a session management scheme that resists such attacks. Consider the following scheme of 3 cookies, each containing a long, independently random string.
We have the browser access the "challenge" cookie via script and put a copy in the request data for each request before it is sent. Then on the server side, we have the server read the "browser" and "session" cookies from the Cookie header, but read the "challenge" cookie only from the request body.
This proves to the server that whatever page generated the request had access to the cookie, and since the browser is supposed to enforce the rule that only pages on example.com will be able to do so, the server may conclude that the request was in fact generated from a page on example.com. Therefore CSRF attacks, as they are currently defined, are not possible.
Finally the "browser" cookie is a persistent cookie that is used to identify the specific browser being used by the user. This cookie is designed to protect against credential-theft attacks, and doesn't have anything to do with CSRF. It is discussed here in order to illustrate an additional type of cookie for the sake of completeness. In the case when each user uses a single browser exclusively to access the Web application (e.g. the system default browser on their company-managed laptop), this cookie is useful as an additional factor in the authentication scheme.
In particular, if an attacker using a different browser tries to create a session by entering a victim user's stolen credentials, the server will see that the "browser" cookie is missing or incorrect, and issue an additional out-of-band challenge in order to complete the login process. For example, the application can send the user an email or text message containing a random code, and require the user to enter it with the usual credentials in order to log in.
If the attacker isn't also able to compromise the victim's email account or phone, or somehow get access to the victim's computer to read the cookie, it won't be possible to create a session, and the attack will fail. Genuine users who respond successfully with the correct code will receive the browser cookie, which is set as a persistent cookie so that the additional login step won't be required again for a while.
Of course if browser security fails in some way, for example through a flaw in the HTTPS implementation, or a flaw in same-origin security rules, the security measures described here won't provide much protection. And if you have an existing Web application whose design is incompatible with the above measures, it may be cost-prohibitive to implement them. But for new projects, it is a good idea to consider in advance the kind of attacks that have plagued existing applications, and design around them.