diff --git a/resources/sql/patches/20130530.sessionhash.php b/resources/sql/patches/20130530.sessionhash.php index 4efbe5feec..771dac61e3 100644 --- a/resources/sql/patches/20130530.sessionhash.php +++ b/resources/sql/patches/20130530.sessionhash.php @@ -14,7 +14,7 @@ foreach ($sessions as $session) { $conn, 'UPDATE %T SET sessionKey = %s WHERE userPHID = %s AND type = %s', PhabricatorUser::SESSION_TABLE, - PhabricatorHash::digest($session['sessionKey']), + PhabricatorHash::weakDigest($session['sessionKey']), $session['userPHID'], $session['type']); } diff --git a/src/applications/auth/controller/PhabricatorAuthController.php b/src/applications/auth/controller/PhabricatorAuthController.php index 4a572edf22..c5b3c1ce99 100644 --- a/src/applications/auth/controller/PhabricatorAuthController.php +++ b/src/applications/auth/controller/PhabricatorAuthController.php @@ -194,7 +194,7 @@ abstract class PhabricatorAuthController extends PhabricatorController { // hijacking registration sessions. $actual = $account->getProperty('registrationKey'); - $expect = PhabricatorHash::digest($registration_key); + $expect = PhabricatorHash::weakDigest($registration_key); if (!phutil_hashes_are_identical($actual, $expect)) { $response = $this->renderError( pht( diff --git a/src/applications/auth/controller/PhabricatorAuthLoginController.php b/src/applications/auth/controller/PhabricatorAuthLoginController.php index b9b2a8d876..3264e61216 100644 --- a/src/applications/auth/controller/PhabricatorAuthLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthLoginController.php @@ -194,7 +194,7 @@ final class PhabricatorAuthLoginController $registration_key = Filesystem::readRandomCharacters(32); $account->setProperty( 'registrationKey', - PhabricatorHash::digest($registration_key)); + PhabricatorHash::weakDigest($registration_key)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $account->save(); diff --git a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php index 627d1b43eb..ebfd07e7ac 100644 --- a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php @@ -135,7 +135,7 @@ final class PhabricatorAuthOneTimeLoginController ->setTokenResource($target_user->getPHID()) ->setTokenType($password_type) ->setTokenExpires(time() + phutil_units('1 hour in seconds')) - ->setTokenCode(PhabricatorHash::digest($key)) + ->setTokenCode(PhabricatorHash::weakDigest($key)) ->save(); unset($unguarded); diff --git a/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php b/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php index 43ac80bb70..fa58977c90 100644 --- a/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php +++ b/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php @@ -16,7 +16,7 @@ final class PhabricatorAuthTerminateSessionController $query->withIDs(array($id)); } - $current_key = PhabricatorHash::digest( + $current_key = PhabricatorHash::weakDigest( $request->getCookie(PhabricatorCookies::COOKIE_SESSION)); $sessions = $query->execute(); diff --git a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php index 4e66d3c9f4..82303fff2b 100644 --- a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php +++ b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php @@ -110,7 +110,7 @@ final class PhabricatorAuthSessionEngine extends Phobject { $session_table = new PhabricatorAuthSession(); $user_table = new PhabricatorUser(); $conn_r = $session_table->establishConnection('r'); - $session_key = PhabricatorHash::digest($session_token); + $session_key = PhabricatorHash::weakDigest($session_token); $cache_parts = $this->getUserCacheQueryParts($conn_r); list($cache_selects, $cache_joins, $cache_map, $types_map) = $cache_parts; @@ -240,7 +240,7 @@ final class PhabricatorAuthSessionEngine extends Phobject { // This has a side effect of validating the session type. $session_ttl = PhabricatorAuthSession::getSessionTypeTTL($session_type); - $digest_key = PhabricatorHash::digest($session_key); + $digest_key = PhabricatorHash::weakDigest($session_key); // Logging-in users don't have CSRF stuff yet, so we have to unguard this // write. @@ -306,7 +306,7 @@ final class PhabricatorAuthSessionEngine extends Phobject { ->execute(); if ($except_session !== null) { - $except_session = PhabricatorHash::digest($except_session); + $except_session = PhabricatorHash::weakDigest($except_session); } foreach ($sessions as $key => $session) { @@ -755,7 +755,7 @@ final class PhabricatorAuthSessionEngine extends Phobject { $parts[] = $email->getVerificationCode(); } - return PhabricatorHash::digest(implode(':', $parts)); + return PhabricatorHash::weakDigest(implode(':', $parts)); } diff --git a/src/applications/auth/factor/PhabricatorTOTPAuthFactor.php b/src/applications/auth/factor/PhabricatorTOTPAuthFactor.php index 8875b960e2..10c44aaec0 100644 --- a/src/applications/auth/factor/PhabricatorTOTPAuthFactor.php +++ b/src/applications/auth/factor/PhabricatorTOTPAuthFactor.php @@ -39,7 +39,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor { ->withTokenResources(array($user->getPHID())) ->withTokenTypes(array($totp_token_type)) ->withExpired(false) - ->withTokenCodes(array(PhabricatorHash::digest($key))) + ->withTokenCodes(array(PhabricatorHash::weakDigest($key))) ->executeOne(); if (!$temporary_token) { // If we don't have a matching token, regenerate the key below. @@ -58,7 +58,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor { ->setTokenResource($user->getPHID()) ->setTokenType($totp_token_type) ->setTokenExpires(time() + phutil_units('1 hour in seconds')) - ->setTokenCode(PhabricatorHash::digest($key)) + ->setTokenCode(PhabricatorHash::weakDigest($key)) ->save(); unset($unguarded); } diff --git a/src/applications/auth/provider/PhabricatorAuthProvider.php b/src/applications/auth/provider/PhabricatorAuthProvider.php index a3f77618e4..4dd7f4da1b 100644 --- a/src/applications/auth/provider/PhabricatorAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorAuthProvider.php @@ -474,7 +474,7 @@ abstract class PhabricatorAuthProvider extends Phobject { true); } - return PhabricatorHash::digest($phcid); + return PhabricatorHash::weakDigest($phcid); } protected function verifyAuthCSRFCode(AphrontRequest $request, $actual) { diff --git a/src/applications/auth/query/PhabricatorAuthSessionQuery.php b/src/applications/auth/query/PhabricatorAuthSessionQuery.php index 966bb946c4..dea95dd450 100644 --- a/src/applications/auth/query/PhabricatorAuthSessionQuery.php +++ b/src/applications/auth/query/PhabricatorAuthSessionQuery.php @@ -85,7 +85,7 @@ final class PhabricatorAuthSessionQuery if ($this->sessionKeys) { $hashes = array(); foreach ($this->sessionKeys as $session_key) { - $hashes[] = PhabricatorHash::digest($session_key); + $hashes[] = PhabricatorHash::weakDigest($session_key); } $where[] = qsprintf( $conn_r, diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index f2b267b67f..58d8f6cf6f 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -98,7 +98,7 @@ abstract class PhabricatorController extends AphrontController { if (!$user->isLoggedIn()) { - $user->attachAlternateCSRFString(PhabricatorHash::digest($phsid)); + $user->attachAlternateCSRFString(PhabricatorHash::weakDigest($phsid)); } $request->setUser($user); diff --git a/src/applications/celerity/resources/CelerityResources.php b/src/applications/celerity/resources/CelerityResources.php index 9536786a6a..e0b9191702 100644 --- a/src/applications/celerity/resources/CelerityResources.php +++ b/src/applications/celerity/resources/CelerityResources.php @@ -14,7 +14,7 @@ abstract class CelerityResources extends Phobject { public function getCelerityHash($data) { $tail = PhabricatorEnv::getEnvConfig('celerity.resource-hash'); - $hash = PhabricatorHash::digest($data, $tail); + $hash = PhabricatorHash::weakDigest($data, $tail); return substr($hash, 0, 8); } diff --git a/src/applications/config/check/PhabricatorPathSetupCheck.php b/src/applications/config/check/PhabricatorPathSetupCheck.php index 9f5502e215..75c89d332a 100644 --- a/src/applications/config/check/PhabricatorPathSetupCheck.php +++ b/src/applications/config/check/PhabricatorPathSetupCheck.php @@ -107,7 +107,7 @@ final class PhabricatorPathSetupCheck extends PhabricatorSetupCheck { if ($bad_paths) { foreach ($bad_paths as $path_part => $message) { - $digest = substr(PhabricatorHash::digest($path_part), 0, 8); + $digest = substr(PhabricatorHash::weakDigest($path_part), 0, 8); $this ->newIssue('config.PATH.'.$digest) diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php index 02ff23b15f..5e61ae3a7c 100644 --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -652,7 +652,7 @@ final class DiffusionServeController extends DiffusionController { } $lfs_pass = $password->openEnvelope(); - $lfs_hash = PhabricatorHash::digest($lfs_pass); + $lfs_hash = PhabricatorHash::weakDigest($lfs_pass); $token = id(new PhabricatorAuthTemporaryTokenQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) diff --git a/src/applications/diffusion/gitlfs/DiffusionGitLFSTemporaryTokenType.php b/src/applications/diffusion/gitlfs/DiffusionGitLFSTemporaryTokenType.php index 0973072ba4..e5425b07e1 100644 --- a/src/applications/diffusion/gitlfs/DiffusionGitLFSTemporaryTokenType.php +++ b/src/applications/diffusion/gitlfs/DiffusionGitLFSTemporaryTokenType.php @@ -22,7 +22,7 @@ final class DiffusionGitLFSTemporaryTokenType $lfs_user = self::HTTP_USERNAME; $lfs_pass = Filesystem::readRandomCharacters(32); - $lfs_hash = PhabricatorHash::digest($lfs_pass); + $lfs_hash = PhabricatorHash::weakDigest($lfs_pass); $ttl = PhabricatorTime::getNow() + phutil_units('1 day in seconds'); diff --git a/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php b/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php index 0bbeeeac6c..1bb86cf67e 100644 --- a/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php +++ b/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php @@ -102,7 +102,7 @@ final class PhabricatorChunkedFileStorageEngine } public static function getChunkedHashForInput($input) { - $rehash = PhabricatorHash::digest($input); + $rehash = PhabricatorHash::weakDigest($input); // Add a suffix to identify this as a chunk hash. $rehash = substr($rehash, 0, -2).'-C'; diff --git a/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php b/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php index 52a9a78a19..5985458ab4 100644 --- a/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php +++ b/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php @@ -201,7 +201,7 @@ abstract class PhabricatorObjectMailReceiver extends PhabricatorMailReceiver { public static function computeMailHash($mail_key, $phid) { $global_mail_key = PhabricatorEnv::getEnvConfig('phabricator.mail-key'); - $hash = PhabricatorHash::digest($mail_key.$global_mail_key.$phid); + $hash = PhabricatorHash::weakDigest($mail_key.$global_mail_key.$phid); return substr($hash, 0, 16); } diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php index 7edbcd4e52..4a35d9956c 100644 --- a/src/applications/people/storage/PhabricatorUser.php +++ b/src/applications/people/storage/PhabricatorUser.php @@ -389,7 +389,7 @@ final class PhabricatorUser // Generate a token hash to mitigate BREACH attacks against SSL. See // discussion in T3684. $token = $this->getRawCSRFToken(); - $hash = PhabricatorHash::digest($token, $salt); + $hash = PhabricatorHash::weakDigest($token, $salt); return self::CSRF_BREACH_PREFIX.$salt.substr( $hash, 0, self::CSRF_TOKEN_LENGTH); } @@ -435,7 +435,7 @@ final class PhabricatorUser for ($ii = -$csrf_window; $ii <= 1; $ii++) { $valid = $this->getRawCSRFToken($ii); - $digest = PhabricatorHash::digest($valid, $salt); + $digest = PhabricatorHash::weakDigest($valid, $salt); $digest = substr($digest, 0, self::CSRF_TOKEN_LENGTH); if (phutil_hashes_are_identical($digest, $token)) { return true; @@ -459,7 +459,7 @@ final class PhabricatorUser $time_block = floor($epoch / $frequency); $vec = $vec.$key.$time_block; - return substr(PhabricatorHash::digest($vec), 0, $len); + return substr(PhabricatorHash::weakDigest($vec), 0, $len); } public function getUserProfile() { diff --git a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php index fa91dac210..17b8cdde95 100644 --- a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php @@ -48,7 +48,7 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel { ->setViewer($user) ->withTokenResources(array($user->getPHID())) ->withTokenTypes(array($password_type)) - ->withTokenCodes(array(PhabricatorHash::digest($key))) + ->withTokenCodes(array(PhabricatorHash::weakDigest($key))) ->withExpired(false) ->executeOne(); } diff --git a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php index e3a37c9dfc..a468ed53d0 100644 --- a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php @@ -44,7 +44,7 @@ final class PhabricatorSessionsSettingsPanel extends PhabricatorSettingsPanel { ->withPHIDs($identity_phids) ->execute(); - $current_key = PhabricatorHash::digest( + $current_key = PhabricatorHash::weakDigest( $request->getCookie(PhabricatorCookies::COOKIE_SESSION)); $rows = array(); diff --git a/src/infrastructure/util/PhabricatorHash.php b/src/infrastructure/util/PhabricatorHash.php index dc13b85dbe..19c8414539 100644 --- a/src/infrastructure/util/PhabricatorHash.php +++ b/src/infrastructure/util/PhabricatorHash.php @@ -5,12 +5,15 @@ final class PhabricatorHash extends Phobject { const INDEX_DIGEST_LENGTH = 12; /** - * Digest a string for general use, including use which relates to security. + * Digest a string using HMAC+SHA1. + * + * Because a SHA1 collision is now known, this method should be considered + * weak. Callers should prefer @{method:digestWithNamedKey}. * * @param string Input string. * @return string 32-byte hexidecimal SHA1+HMAC hash. */ - public static function digest($string, $key = null) { + public static function weakDigest($string, $key = null) { if ($key === null) { $key = PhabricatorEnv::getEnvConfig('security.hmac-key'); } @@ -37,7 +40,7 @@ final class PhabricatorHash extends Phobject { } for ($ii = 0; $ii < 1000; $ii++) { - $result = self::digest($result, $salt); + $result = self::weakDigest($result, $salt); } return $result;