From: Brian Wolff Date: Tue, 15 Nov 2016 06:09:24 +0000 (+0000) Subject: Throw an exception if password hash would be truncated by DB X-Git-Tag: 1.31.0-rc.0~4718^2 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dmembres/cotisations/gestion/rappel_supprimer.php?a=commitdiff_plain;h=e8589233bc3e0c776e2acf36761d3f9b4eb82f04;p=lhc%2Fweb%2Fwiklou.git Throw an exception if password hash would be truncated by DB DB uses a tinyblob field. With layered encrypted passwords, the length gets close to 255 and can exceed if you use a long name for the password type. Previously these would be silently inserted into the DB and truncated, which would lock user out of their account. Change-Id: Idf0d0248b181f42d92e3ad6c3220b5331cd4d4d0 --- diff --git a/includes/password/ParameterizedPassword.php b/includes/password/ParameterizedPassword.php index 954d403bf8..c92979798f 100644 --- a/includes/password/ParameterizedPassword.php +++ b/includes/password/ParameterizedPassword.php @@ -90,7 +90,9 @@ abstract class ParameterizedPassword extends Password { $str .= $this->getDelimiter(); } - return $str . $this->hash; + $res = $str . $this->hash; + $this->assertIsSafeSize( $res ); + return $res; } /** diff --git a/includes/password/Password.php b/includes/password/Password.php index 4e395b5182..13d1e6deba 100644 --- a/includes/password/Password.php +++ b/includes/password/Password.php @@ -81,6 +81,11 @@ abstract class Password { */ protected $config; + /** + * Hash must fit in user_password, which is a tinyblob + */ + const MAX_HASH_SIZE = 255; + /** * Construct the Password object using a string hash * @@ -168,9 +173,28 @@ abstract class Password { * are considered equivalent. * * @return string + * @throws PasswordError if password cannot be serialized to fit a tinyblob. */ public function toString() { - return ':' . $this->config['type'] . ':' . $this->hash; + $result = ':' . $this->config['type'] . ':' . $this->hash; + $this->assertIsSafeSize( $result ); + return $result; + } + + /** + * Assert that hash will fit in a tinyblob field. + * + * This prevents MW from inserting it into the DB + * and having MySQL silently truncating it, locking + * the user out of their account. + * + * @param string $hash The hash in question. + * @throws PasswordError If hash does not fit in DB. + */ + final protected function assertIsSafeSize( $hash ) { + if ( strlen( $hash ) > self::MAX_HASH_SIZE ) { + throw new PasswordError( "Password hash is too big" ); + } } /**