senchalabs/connect — pull request #866 by AgentME (2013-08-15 06:11:34+00:00)
Title: Security: Fix BREACH attack against CSRF tokens by not re-using CSRF tokens.

The recently-revealed [BREACH attack](https://www.kb.cert.org/vuls/id/987798) can be used against users on HTTPS-secured sites to reveal static secrets, including anti-CSRF tokens. The attack relies on secrets being static over multiple requests. At least [one other web framework has recognized this specific issue](https://www.djangoproject.com/weblog/2013/aug/06/breach-and-django/). This patch makes it so users aren't given the same CSRF token multiple times, making it not possible for them to be revealed by a BREACH attack. (This is the third solution on the linked CERT page.)

Instead of a CSRF token being stored in the user's session, a "CSRF secret" is stored in the user's session, which CSRF tokens are derived from. Creating tokens isn't that expensive, but their creation is on-demand so that they aren't generated for requests that don't use them. The tokens are created by generating a random 10 character salt, and then appending sha1(salt + secret) to it. Tokens can be submitted by a client multiple times, though if an application can avoid it simply then I'd recommend it, or else an admittedly difficult BREACH attack variant may be possible.

A CSRF token can be generated by calling `req._csrf()`. A getter is defined at `req.session._csrf` so that old code that uses it can continue to work, while avoiding needlessly modifying the underlying session every request for a new token. (The defined getter is not saved into the underlying session storage.) Using `req.session._csrf` will print a deprecation warning.