VYPR
Medium severity5.9NVD Advisory· Published Sep 1, 2017· Updated May 13, 2026

CVE-2017-12872

CVE-2017-12872

Description

The (1) Htpasswd authentication source in the authcrypt module and (2) SimpleSAML_Session class in SimpleSAMLphp 1.14.11 and earlier allow remote attackers to conduct timing side-channel attacks by leveraging use of the standard comparison operator to compare secret material against user input.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
simplesamlphp/simplesamlphpPackagist
< 1.15.0-rc11.15.0-rc1

Affected products

3
  • cpe:2.3:a:simplesamlphp:simplesamlphp:*:*:*:*:*:*:*:*
    Range: <=1.14.11
  • cpe:2.3:o:debian:debian_linux:7.0:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:o:debian:debian_linux:7.0:*:*:*:*:*:*:*
    • cpe:2.3:o:debian:debian_linux:8.0:*:*:*:*:*:*:*

Patches

1
b72c79e3070f

Add a SimpleSAML\Utils\Crypto::secureCompare() method.

https://github.com/simplesamlphp/simplesamlphpJaime Pérez CrespoMar 17, 2017via ghsa
3 files changed · +38 4
  • lib/SimpleSAML/Session.php+1 1 modified
    @@ -353,7 +353,7 @@ public static function getSession($sessionId = null)
                         SimpleSAML\Logger::warning('Missing AuthToken cookie.');
                         return null;
                     }
    -                if ($_COOKIE[$authTokenCookieName] !== $session->authToken) {
    +                if (!SimpleSAML\Utils\Crypto::secureCompare($session->authToken, $_COOKIE[$authTokenCookieName])) {
                         SimpleSAML\Logger::warning('Invalid AuthToken cookie.');
                         return null;
                     }
    
  • lib/SimpleSAML/Utils/Crypto.php+34 2 modified
    @@ -349,6 +349,38 @@ public static function pwHash($password, $algorithm, $salt = null)
         }
     
     
    +    /**
    +     * Compare two strings securely.
    +     *
    +     * This method checks if two strings are equal in constant time, avoiding timing attacks. Use it every time we need
    +     * to compare a string with a secret that shouldn't be leaked, i.e. when verifying passwords, one-time codes, etc.
    +     *
    +     * @param string $known A known string.
    +     * @param string $user A user-provided string to compare with the known string.
    +     *
    +     * @return bool True if both strings are equal, false otherwise.
    +     */
    +    public static function secureCompare($known, $user)
    +    {
    +        if (function_exists('hash_equals')) {
    +            // use hash_equals() if available (PHP >= 5.6)
    +            return hash_equals($known, $user);
    +        }
    +
    +        // compare manually in constant time
    +        $len = mb_strlen($known, '8bit'); // see mbstring.func_overload
    +        if ($len !== mb_strlen($user, '8bit')) {
    +            return false; // length differs
    +        }
    +        $diff = 0;
    +        for ($i = 0; $i < $len; ++$i) {
    +            $diff |= $known[$i] ^ $user[$i];
    +        }
    +        // if all the bytes in $a and $b are identical, $diff should be equal to 0
    +        return $diff === 0;
    +    }
    +
    +
         /**
          * This function checks if a password is valid
          *
    @@ -374,7 +406,7 @@ public static function pwValid($hash, $password)
     
                 // hash w/o salt
                 if (in_array(strtolower($alg), hash_algos())) {
    -                return $hash === self::pwHash($password, $alg);
    +                return self::secureCompare($hash, self::pwHash($password, $alg));
                 }
     
                 // hash w/ salt
    @@ -384,7 +416,7 @@ public static function pwValid($hash, $password)
                     // get hash length of this algorithm to learn how long the salt is
                     $hash_length = strlen(hash($php_alg, '', true));
                     $salt = substr(base64_decode($matches[2]), $hash_length);
    -                return ($hash === self::pwHash($password, $alg, $salt));
    +                return self::secureCompare($hash, self::pwHash($password, $alg, $salt));
                 }
             } else {
                 return $hash === $password;
    
  • modules/authcrypt/lib/Auth/Source/Htpasswd.php+3 1 modified
    @@ -74,8 +74,9 @@ protected function login($username, $password) {
     				$attributes = array_merge(array('uid' => array($username)), $this->attributes);
     
     				// Traditional crypt(3)
    -				if(crypt($password, $crypted) == $crypted) {
    +				if (SimpleSAML\Utils\Crypto::secureCompare($crypted, crypt($password, $crypted))) {
     					SimpleSAML\Logger::debug('User '. $username . ' authenticated successfully');
    +					SimpleSAML\Logger::warning('CRYPT authentication is insecure. Please consider using something else.');
     					return $attributes;
     				}
     
    @@ -88,6 +89,7 @@ protected function login($username, $password) {
     				// SHA1 or plain-text
     				if(SimpleSAML\Utils\Crypto::pwValid($crypted, $password)) {
     					SimpleSAML\Logger::debug('User '. $username . ' authenticated successfully');
    +					SimpleSAML\Logger::warning('SHA1 and PLAIN TEXT authentication are insecure. Please consider using something else.');
     					return $attributes;
     				}
     				throw new SimpleSAML_Error_Error('WRONGUSERPASS');
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.