Browse Source

Merge pull request #6142 from cakephp/issue-6139

Fix timing side channel in HMAC comparison

Refs #6139
Mark Story 11 years ago
parent
commit
113ebb19bc
2 changed files with 29 additions and 1 deletions
  1. 26 1
      src/Utility/Security.php
  2. 3 0
      src/Utility/Text.php

+ 26 - 1
src/Utility/Security.php

@@ -227,7 +227,7 @@ class Security
         $cipher = substr($cipher, $macSize);
 
         $compareHmac = hash_hmac('sha256', $cipher, $key);
-        if ($hmac !== $compareHmac) {
+        if (!static::_constantEquals($hmac, $compareHmac)) {
             return false;
         }
 
@@ -236,6 +236,31 @@ class Security
     }
 
     /**
+     * A timing attack resistant comparison that prefers native PHP implementations.
+     *
+     * @param string $hmac The hmac from the ciphertext being decrypted.
+     * @param string $compare The comparison hmac.
+     * @return bool
+     * @see https://github.com/resonantcore/php-future/
+     */
+    protected static function _constantEquals($hmac, $compare)
+    {
+        if (function_exists('hash_equals')) {
+            return hash_equals($hmac, $compare);
+        }
+        $hashLength = strlen($hmac);
+        $compareLength = strlen($compare);
+        if ($hashLength !== $compareLength) {
+            return false;
+        }
+        $result = 0;
+        for ($i = 0; $i < $hashLength; $i++) {
+            $result |= (ord($hmac[$i]) ^ ord($compare[$i]));
+        }
+        return $result === 0;
+    }
+
+    /**
      * Gets or sets the HMAC salt to be used for encryption/decryption
      * routines.
      *

+ 3 - 0
src/Utility/Text.php

@@ -26,6 +26,9 @@ class Text
     /**
      * Generate a random UUID version 4
      *
+     * Warning: This method should not be used as a random seed for any cryptographic operations.
+     * Instead you should use the openssl or mcrypt extensions.
+     *
      * @see http://www.ietf.org/rfc/rfc4122.txt
      * @return string RFC 4122 UUID
      * @copyright Matt Farina MIT License https://github.com/lootils/uuid/blob/master/LICENSE