Session cookies for web applications [http://lwn.net/Articles/283383/]
By Jake Edge
May 21, 2008
Two weeks ago on this page, we reported on some Wordpress vulnerabilities that were caused by incorrectly generating authentication cookies. The article was a bit light on details about such cookies, so this follow-up hopes to remedy that. In addition, Steven Murdoch, who discovered both of the holes, recently presented a paper on a new cookie technique that provides some additional safeguards over other schemes.
两周前在此页上,我们报道了由不正确生成的身份验证 cookies 引起的一些 Wordpress 漏洞。那篇文档对这些 cookies 的细节描述略少,这篇后续的文章希望能解决这个问题。另外,发现这些漏洞的 Steven Murdoch,最近发表了篇关于一种新的 cookie 技术的文章,文章提供了其他方案之`上`的一些额外保护措施。
HTTP is a stateless protocol which means that any application that wishes to track multiple requests as a single session must provide its own way to link those requests. This is typically done through cookies, which are opaque blobs of data that are stored by browsers. Cookies are sent to the browser as part of an HTTP response, usually after some kind of authentication is successful. The browser associates the cookie with the URL of the site so that it can send the cookie value back to the server on each subsequent request.
HTTP 是一种无状态的协议,这意味着任何希望跟踪多个请求作为单个会话的应用程序,必须提供自己的方式来链接这些请求。这通常通过 cookies 来完成,cookies 是浏览器存储的不透明的数据块。通常,在某种身份认证成功后,cookies 被作为一个 HTTP 响应的一部分发送给浏览器。浏览器把 cookie 和对应网站的 URL 关联起来,以便它可以在每个后续请求中回送 cookie 值到服务器。
Servers can then use the value as a key into some kind of persistent storage so that all requests that contain that cookie value are treated as belonging to a particular session. In particular, it represents that the user associated with that session has correctly authenticated. The cookie lasts until it expires or is deleted by the user. When that happens, the user must re-authenticate to get a new cookie which also starts a new session. Users find this annoying if it happens too frequently, so expirations are often quite long.
然后,服务器可以`用某种持久性存储的键`使用该值,使得所有包含该 cookie 值的请求,被视为属于同一个特定会话。特别是,它代表和该会话关联的那个已经正确通过身份验证的用户。一个 cookie 一直存在,直到过期或被用户删除。此时,用户必须重新进行身份验证,获取一个新 cookie,同时开始一个新会话。如果它发生的过于频繁,会让用户感到恼人,所以到期时间通常相当长。
If the user explicitly logs out of the application, any server-side resources that are being used to store state information can be freed, but that is often not the case. Users will generally just close their browser (or tab) while still being logged in. It is also convenient for users to be allowed multiple concurrent sessions, generally from multiple computers, which will cause the number of sessions stored to be larger, perhaps much larger, than the number of users.
如果用户显式地登出应用程序,任何用来存储状态信息的服务器端资源会被释放,但情况经常不是这样。用户通常只是关闭他们的浏览器(或标签页),当仍在登录状态时。这也允许用户方便地,从不同的计算机上使用多个并发会话。这将导致存储更大的会话数量,也许比用户数量大许多。
Applications could restrict the number of sessions allowed by a user, or ratchet the expiration value way down, but they typically do not for user convenience. This allows for a potential denial of service when an attacker creates so many sessions that the server runs out of persistent storage. For this reason, stateless session cookies [PDF][http://prisms.cs.umass.edu/~kevinfu/papers/webauth_tr.pdf] were created.
应用程序可以限制允许一个用户使用的会话数,或者``,但它们通常不方便用户使用。这允许一个潜在的拒绝服务,当一个攻击者创建太多会话,以至于服务器用完持久性存储时。出于这个原因,无状态会话 cookies 被创建。
Stateless session cookies store all of the state information in the cookie itself, so that the server need not keep anything in the database, filesystem, or memory. The data in the cookie must be encoded in such a way that they cannot be forged, otherwise attackers could create cookies that allow them access they should not have. This is essentially where Wordpress went wrong. By not implementing stateless session cookies correctly, a valid cookie for one user could be modified into a valid cookie for a different user.
无状态会话 cookies 把所有状态信息存储到 cookie 本身,使服务器不需要在数据库、文件系统或内存中保存任何信息。Cookie 中的数据必须以不能被伪造的方式编码,否则攻击者可以创建允许他们访问不应该访问内容的 cookies 。实际上这就是 Wordpress 出问题的地方。由于没有正确使用无状态会话 cookies ,一个用户的有效 cookie 可以被修改成另一个不同用户的有效 cookie 。
A stateless session cookie has the state data and expiration "in the clear" followed by a secure hash (SHA-256 for example) of those same values along with a key known only by the server. When the server receives the cookie value, it can calculate the hash and if it matches, proceed to use the state information. Because the secret is not known, an attacker cannot create their own cookies with values of their choosing.
一个无状态的会话 cookie 有状态数据和明确的到期时间,后跟一个安全哈希值(例如 SHA-256),该哈希值和只有服务器知道的一个键`对应`。当服务器接收到 cookie 值,会计算哈希值,如果匹配,继续使用其中的状态信息。由于这个密钥是未知的,攻击者不能使用他们选择的值创建自己的 cookies 。
The other side of that coin is that an attacker can create spoofed cookies if they know the secret. Murdoch wanted to extend the concept such that even getting access to the secret, through a SQL injection or other web application flaw, would not feasibly allow an attacker to create a spoofed cookie. The result is hardened stateless session cookies [PDF][http://www.cl.cam.ac.uk/~sjm217/papers/protocols08cookies.pdf].
硬币的另一面是,如果攻击者知道密钥,可以创建欺骗性的 cookies 。Murdoch 希望扩展概念,使得通过 SQL 注入或其它 web 应用漏洞访问密钥后,攻击者也无法创建一个欺骗性的 cookie。结果就是强化的无状态会话 cookies 。
The basic idea behind the scheme is to add an additional field to stateless session cookies that corresponds to an authenticator generated when an account is first set up. This authenticator is generated from the password at account creation by iteratively calculating the cryptographic hash of the password and a long salt value.
该方案背后的基本思路是,给无状态会话 cookie 增加一个额外的字段,这个字段和账户首次设置时生成的一个`身份验证器`对应。身份验证器由创建账户时的密码生成,生成方法是,迭代计算密码的加密哈希和一个长 salt 值。
Salt is a random string—usually just a few characters long—that is added to a password before it gets hashed, then stored with the password in the clear. It is used to eliminate the use of rainbow tables to crack passwords. Hardened stateless session cookies use a 128-bit salt value, then repeatedly calculate HASH(prev|salt), where prev is the password the first time through and the hash value from the previous calculation on each subsequent iteration.
Salt 是一个随机字符串——通常只有几个字符长——它在被计算哈希值前添加到密码中,然后以明文形式和密码一起存储。它是用来杜绝使用彩虹表破解密码的。`硬化`的无状态会话 cookies 使用128位 salt 值,然后迭代计算 HASH(prev|salt) , 其中 prev 在第一次迭代时是密码,在以后每次迭代中是上次计算的 hash 值。
The number of iterations is large, 256 for example, but not a secret. Once that value is calculated, it is hashed one last time, without the salt, and then stored in the user table as the authenticator. When the cookie value is created after a successful authentication, only the output of the iterative hash itself is placed in the cookie, not the authenticator that is stored in the database. Cookie verification then must do the standard stateless session cookie hash verification, to ensure that the values have not been manipulated, then hash the value in the cookie to verify against authenticator in the database.
迭代次数是个大的值,例如256,但这不是保密的。值被计算出来后,再不使用 salt 哈希一次,然后作为身份验证器存储到用户表中。当 cookie 通过一次成功认证被创建后,只有输出的迭代哈希值被保存在 cookie 中,而不保存数据库中的身份验证器。Cookie 验证必须进行标准的无状态会话 cookie 哈希验证,来确保值没有被修改过,然后哈希 cookie 中的值和数据库中的身份验证器对比。
If it sounds complicated, it is; the performance of doing 256 hashes is also an issue, but it does protect against the secret key being lost. Because an attacker cannot calculate a valid authenticator value to put in the cookie (doing so would require breaking SHA-256), they cannot create their own spoofed cookies.
如果这听起来很复杂,确实;进行256次哈希的性能也是一个问题,但它确实能避免密钥丢失。因为攻击者无法计算一个有效的用户验证器放进 cookie 中(这样做需要突破 SHA-256),所以他们不能创建自己的欺骗 cookie 。
While it is not clear that the overhead of all of these hash calculations is warranted, it is an interesting extension to the stateless session cookie scheme. In his paper, Murdoch mentions some variations that could be used to further increase the security of the technique.
目前尚不清楚所有这些哈希计算的开销是否有必要,这是一个扩展无状态会话 cookie 的有趣方案。在他的文章中,Murdoch 提到了一些可以进一步提高该技术安全性的变化。
---
后面没看明白。
无状态会话 cookie 中的密钥可能被攻击者获取,authenticator 为什么不能被攻击者获取?获取这两个东西的难度有区别么?
---
TODO
| hash salt
| 彩虹表