Quellcode durchsuchen

[Security] changed the way passwords are compared to avoid timing attacks

Fabien Potencier vor 14 Jahren
Ursprung
Commit
0749038e73

+ 25 - 0
src/Symfony/Component/Security/Encoder/BasePasswordEncoder.php

@@ -63,4 +63,29 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
 
         return $password.'{'.$salt.'}';
     }
+
+    /**
+     * Compares two passwords.
+     *
+     * This method implements a constant-time algorithm to compare
+     * passwords to avoid (remote) timing attacks.
+     *
+     * @param string $password1 The first password
+     * @param string $password2 The second password
+     *
+     * @return Boolean true if the two passwords are the same, false otherwise
+     */
+    protected function comparePasswords($password1, $password2)
+    {
+        if (strlen($password1) !== strlen($password2)) {
+            return false;
+        }
+
+        $result = 0;
+        for ($i = 0; $i < strlen($password1); $i++) {
+            $result |= ord($password1[$i]) ^ ord($password2[$i]);
+        }
+
+        return 0 === $result;
+    }
 }

+ 1 - 1
src/Symfony/Component/Security/Encoder/MessageDigestPasswordEncoder.php

@@ -56,6 +56,6 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder
      */
     public function isPasswordValid($encoded, $raw, $salt)
     {
-        return $encoded === $this->encodePassword($raw, $salt);
+        return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
     }
 }

+ 2 - 2
src/Symfony/Component/Security/Encoder/PlaintextPasswordEncoder.php

@@ -41,9 +41,9 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder
         $pass2 = $this->mergePasswordAndSalt($raw, $salt);
 
         if (!$this->ignorePasswordCase) {
-            return $encoded === $pass2;
+            return $this->comparePasswords($encoded, $pass2);
         } else {
-            return strtolower($encoded) === strtolower($pass2);
+            return $this->comparePasswords(strtolower($encoded), strtolower($pass2));
         }
     }
 }