Yes, this does look like a pretty good scheme for protecting cookies.
Another more recent scheme in this area is SCS: Secure Cookie Sessions for HTTP, which is a solid scheme, very well thought-out. I recommend reading the security discussion of that document to get a good sense of what the security threats may be.
To help understand the purpose and role of the cookie scheme you mention, let me back up and provide some context. It is common that web applications need to maintain session state: i.e., some state whose lifetime is limited to the current session, and that is bound to the current session. There are two ways to maintain session state:
- Store session state on the server. The web server feeds the browser a session cookie: a cookie whose only purpose is to hold a large, unguessable bit-string that serves as the session identifier. The server keeps a lookup table, with one entry per open session, that maps from the session identifier to all of the session state associated with this session. This makes it easy for web application code to retrieve and update the session state associated with a particular HTTP/HTTPS request. Most web application frameworks provide built-in support for storing session state on the server side.
This is the most secure way to store session state. Because the session state is stored on the server, the client has no direct access to it. Therefore, there is no way for attackers to read or tamper with session state (or replay old values). It does require some extra work to keep session state synchronized across all servers, if your web application is distributed across multiple back-end compute nodes.
- Store session state on the client. The other approach is to put session state in a cookie and send the cookie to the browser. Now each subsequent request from the browser will include the session state. If the web application wants to modify the session state, it can send an updated cookie to the browser.
If done naively, this is a massive security hole, because it allows a malicious client to view and modify the session state. The former is a problem if there is any confidential data included in the session state. The latter is a problem if the server trusts or relies upon the session state in any way (for example, consider if the session state includes the username of the logged-in user, and a bit indicating whether that user is an administrator or not; then a malicious client could bypass the web application's authentication mechanism).
The proposal you mention, and the SCS scheme, are intended to defend against these risks as well as possible. They can do so in a way that is mostly successful. However, they cannot prevent a malicious client from deleting the cookie (and thus clearing the session state). Also, they cannot prevent a malicious client from replaying an older value of the cookie (and thus resetting the session state to an older value), if the older version came from within the same session. Therefore, the developer of the web application needs to be aware of these risks and take care about what values are stored in session state.
For this reason, storing session state in cookies is a bit riskier than storing it on the server, even if you use one of these cryptographic schemes to protect cookies. (However, if you are going to store session state in cookies, I definitely recommend you use one of these two schemes to protect the values in the cookies.)
Why would anyone store session state in cookies, given that it can just as easily be stored on the server side? Most of the time, there is no reason to. However, in some exceptional cases -- such as a HTTP server that is extremely constrained in the amount of storage it has, or in load-balanced web applications that are distributed across multiple machines without good support for synchronized session state -- there might be justifiable reasons to consider storing session state in cookies, and then using one of these schemes is a good idea.
P.S. A related topic: if you use ASP.NET View State, make sure you configure it to be encrypted and authenticated: i.e., configure ViewStateEncryptionMode
to Always
and EnableViewStateMac
to true
; if you use multiple server nodes, generate a strong cryptographic key and configure each server's machineKey
to use that key. Finally, make sure you have an up-to-date version of the ASP.NET framework; older versions had a serious security flaw in the ViewState crypto.