The bakery module seems to add a signature to the cookie based on parts of the user data. I'm not sure I follow why you bother with such as a signature. The hash is created with the same encryption key as the cookie is encrypted with, so if you can encrypt cookies you can also create the hash correctly, so it doesn't add any security if my understanding is correct.

Should the signature just be removed and to save some CPU cycles?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Steven Jones’s picture

Okay, maybe I do see why it is valuable, you're using the 'ecb' block chaining mode on the encryption, you should probably be using 'cbc' at least.

juliangb’s picture

Any chance of a bit more of an explanation as to why the signature is required, for docs, and why a change of the chaining mode should be made?

Steven Jones’s picture

This one is a little complex, but here's why the hash is currently needed:

Cookie encryption is done using AES in ECB mode, this means that each block of stuff encrypted is done so in isolation, so someone could take a cookie and swap an encrypted block from another cookie into it. It would be a hard attack to pull off, and I could only think that you would somehow swap out the timestamp of the cookie being valid, but the potential is there.

This 'attack' is currently stopped by adding the hash, so that even if some of the critical data is swapped out, then data in the hash won't be.

What should happen is the hash stays (does no harm really) and the encryption mode is changed to CBC, this would require adding an IV setting to the UI.

Does that make sense?

Steven Jones’s picture

Title: Why bother with the signature? » Change encryption to CTR mode and use better signature
Status: Active » Needs review
FileSize
5.8 KB

Attached is a patch that does the following:

Implement encryption/decryption in the style of:
http://www.itnewb.com/v/PHP-Encryption-Decryption-Using-the-MCrypt-Libra...

Changes the cypher mode to CTR.
Uses the users entered key to generate a stronger key.
Moves the signature for tamper prevention into the encryption/decryption function itself, which then validates everything in the payload.

This needs eyes on before anyone even thinks about committing it.

Steven Jones’s picture

Status: Needs review » Needs work
+++ bakery.module	21 Apr 2010 14:48:17 -0000
@@ -666,26 +672,89 @@ function _bakery_eat_cookie($type = 'CHO
+    // This is decryption:
+    // Get the IV:
+    $iv = substr($text, 0, mcrypt_enc_get_iv_size($td));
+    // Get the MAC:
+		$mac_location = strlen($text) - 32;
+		$message_mac = substr($text, $mo);
+		$encrypted_data = substr($text, mcrypt_enc_get_iv_size($td), strlen($text) - (32 + mcrypt_enc_get_iv_size($td)));
+    // Compute the MAC:
+		$mac = bakery_pbkdf2($iv . $encrypted_data, $computed_key, 1000, 32);
+
+    // Make sure that MAC in the message matches the computed $mac
+    if ($mac != $message_mac) {
+      return FALSE;
+    }

This section is just all wrong, tabs and a non-existent $mo variable.

+++ bakery.module	21 Apr 2010 14:48:17 -0000
@@ -666,26 +672,89 @@ function _bakery_eat_cookie($type = 'CHO
+
+/** PBKDF2 Implementation (as described in RFC 2898);
+ *
+ * Slightly modified version from:
+ * http://www.itnewb.com/v/PHP-Encryption-Decryption-Using-the-MCrypt-Library-libmcrypt
+ *
+ *  @param string p password
+ *  @param string s salt
+ *  @param int c iteration count (use 1000 or higher)
+ *  @param int kl derived key length
+ *  @param string a hash algorithm
+ *
+ *  @return string derived key
+*/

Doxygen doesn't meet coding standards.

Powered by Dreditor.

Steven Jones’s picture

Status: Needs work » Needs review
FileSize
9.64 KB

Attached patch addresses the issues above, and adds the following:

  • Wrapper functions for encrypting and decrypting to make things clearer.
  • Use of base64 encoding by default.
  • A better salt. This will need to be configurable in a follow up patch.
  • More documentation.

Should I be patching against 7.x or 6.x?

juliangb’s picture

+++ bakery.module	25 Apr 2010 06:48:29 -0000
@@ -658,34 +658,156 @@ function _bakery_eat_cookie($type = 'CHO
+function bakery_mix($text, $base64encode = TRUE) {
+  return _bakery_encrypt_decrypt($text, TRUE, $base64encode);
+}
...
+function bakery_unmix($text, $base64encode = TRUE) {
+  return _bakery_encrypt_decrypt($text, FALSE, $base64encode);
+}

Is there any reason why we have to have the bakery_mix and bakery_unmix functions now?

By the way, I presume that this patch would have to be tested applied to both the master and slave installation?

Powered by Dreditor.

Steven Jones’s picture

Yup it'll need testing in isolation to make sure the encryption is doing what it should, and in a master/slave environment.

I've added an 'unmix' function because I think it makes it clearer that bakery_mix and bakery_unmix are opposites of each other.

greggles’s picture

This seems like a nice improvement since it also provides the base64 encoding which is useful in other ways.

The variable $base64encode should ideally be $base64_encoded or something to match Drupal style a bit more.

The best person to review this is David Strauss. Any chance you could re-roll it and then we can ping him?

Steven Jones’s picture

Assigned: Unassigned » Steven Jones
Status: Needs review » Needs work

The patch from #6 actually still applies! But I suspect that there are now lots more places that need to be changed a little. I will work on it...

Steven Jones’s picture

Assigned: Steven Jones » Unassigned
Status: Needs work » Needs review
FileSize
10.68 KB

Here's a patch against 7.x-1.x (HEAD). Completely untested.

greggles’s picture

Hmmm, 7.x-1.x-dev isn't the best place for new patches right now but 6.x-2.x is. Any chance you could reroll it for 6.x-2.x?

Steven Jones’s picture

Version: 7.x-1.x-dev » 6.x-2.x-dev
Assigned: Unassigned » Steven Jones

Will look at this when I get a chance.

greggles’s picture

Status: Needs review » Needs work

Updating status to reflect the situation.

Thanks for your help on this, Steven!

coltrane’s picture

Note, if #1013952: Bakery cookies insecure gets in this will need to be updated for it.

Steven Jones’s picture

Assigned: Steven Jones » Unassigned
David Strauss’s picture

Actually, the original reason for the hash is because I wrote the original with minimal data (basically, just username) and no encryption. The encryption and additional data were added later. I support using a more secure encryption method, but encryption should generally not be used in place of signature verification.