openresty / encrypted-session-nginx-module

encrypt and decrypt nginx variable values
http://openresty.org
195 stars 52 forks source link

Use an HMAC, not a simple MD5 hash #3

Open codahale opened 11 years ago

codahale commented 11 years ago

The code, as-is, simply generates an MD5 hash of the data, which is trivially forgeable by an attacker.

Because the authenticity of the session cookie is not guaranteed, the CBC encryption used by this module is vulnerable to padding oracle attacks, which can trivially recover the plaintext of a session cookie.

You should:

  1. Use an HMAC construction, not a simple MD5 hash. OpenSSL provides this.
  2. Use a different key than the key used for encryption.
  3. Create an HMAC of the encrypted data, not of the plaintext.
  4. Use a constant-time comparison algorithm when validating the HMAC to avoid timing attacks.

(Or use an authenticated AES mode like GCM, but this will require OpenSSL 1.0.1+.)

For more details, please see Moxie's blog post on the 'doom principle'.

agentzh commented 11 years ago

@codahale Recovering the clear text of the encrypted session here does not matter. Basically the user should only put a user ID, a number, into it. The user should never put a password or something like that into the encrypted session. What matters here is to avoid faking valid encrypted sessions from arbitrary clear text on the attacker side.

And yeah we can always make the current encryption method stronger :)

codahale commented 11 years ago

Believe me, I understand that, but the module as it exists uses literally none of the cryptographic primitives for providing authentication. You're hoping that CBC mode's confidentiality guarantees are sufficient, which they most certainly aren't.

The fact that session cookies are malleable means there are a variety of adaptive chosen-ciphertext attacks which would allow attackers to take advantage of everyday program features to forge session cookies (e.g., Passki & Ritter's separator oracle).

The fact that the MD5 hash is both completely unauthenticated and of the plaintext data gives attackers an advantage in that they can, after using Vaudenay's adaptive chosen-plaintext attack to decode the contents of their non-admin session cookie, determine the appropriate plaintext for an admin session cookie and know that their forged session cookie works when it passes the MD5 check.

Also, I'm not even a cryptographer. I'm just a guy who's read a few books and was walking past this repo when I got curious. An actual cryptographer—white or black hat—would be able to really dig into this stuff.

Thankfully, the solution here is pretty straight-forward, as I pointed out above.

agentzh commented 11 years ago

@codahale Thank you for the info! I'll look into this :)