April 30, 2015

April 10, 2015

Please reload

Recent Posts

I'm busy working on my blog posts. Watch this space!

Please reload

Featured Posts

CSRF vs. 3 Cookie Session Management

October 25, 2012

 

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.

CookieFlagsExpiration
BrowserSecure,
Http only
90 Days
SessionSecure,
Http only
Session
ChallengeSecureSession

We assume that browsers implement same-origin rules correctly for access to cookies by scripts. In particular, we assume that if a cookie is set for example.com, either through Javascript or in a Set-Cookie header, that only scripts running on pages on example.com will be able to access this cookie data, and pages on other hosts cannot, either through Javascript, or Flash, or Java, or any other way.

We also assume our Web application uses a modern AJAX-based architecture, so that most requests after the initial page load are sent through Javascript. This allows us to easily insert additional data into each request before it is sent, since most requests will be routed through a single AJAX-based dispatch function. We can then deal with non-AJAX requests on a case-by-case basis (file uploads, in particular) as needed.

Given working same-origin rules for cookies and a centralized Javascript-based request framework, our CSRF countermeasure is simple.

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.

Now of course having a cookie accessible by Javascript exposes us to session disclosure via script injection (XSS). That is why we also include the "session" cookie in our management scheme. This cookie is flagged HttpOnly so that Javascript cannot access it. Both cookies are checked by the server, and if either is incorrect or missing the request is denied.

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.

JKL

Share on Facebook
Share on Twitter
Please reload

Follow Us

I'm busy working on my blog posts. Watch this space!

Please reload

Search By Tags