From 69e22f609240544e9733f1f6dbc919dfdd076a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 13 Dec 2022 23:04:28 +0100 Subject: [PATCH] Add #[\SensitiveParameter] attribute to UndisclosedPassword MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This stops the validator from disclosing passwords in the stack trace if the HTTP request fails. Signed-off-by: Tim Düsterhus --- src/UndisclosedPassword.php | 39 +++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/UndisclosedPassword.php b/src/UndisclosedPassword.php index 65a0bbaed..8fd508df6 100644 --- a/src/UndisclosedPassword.php +++ b/src/UndisclosedPassword.php @@ -5,6 +5,7 @@ use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; +use SensitiveParameter; use function array_filter; use function explode; @@ -46,8 +47,10 @@ public function __construct(private ClientInterface $httpClient, private Request } /** {@inheritDoc} */ - public function isValid($value): bool - { + public function isValid( + #[SensitiveParameter] + $value + ): bool { if (! is_string($value)) { $this->error(self::NOT_A_STRING); return false; @@ -61,8 +64,10 @@ public function isValid($value): bool return true; } - private function isPwnedPassword(string $password): bool - { + private function isPwnedPassword( + #[SensitiveParameter] + string $password + ): bool { $sha1Hash = $this->hashPassword($password); $rangeHash = $this->getRangeHash($sha1Hash); $hashList = $this->retrieveHashList($rangeHash); @@ -74,8 +79,10 @@ private function isPwnedPassword(string $password): bool * We use a SHA1 hashed password for checking it against * the breached data set of HIBP. */ - private function hashPassword(string $password): string - { + private function hashPassword( + #[SensitiveParameter] + string $password + ): string { $hashedPassword = sha1($password); return strtoupper($hashedPassword); @@ -87,8 +94,10 @@ private function hashPassword(string $password): string * * @see https://www.troyhunt.com/enhancing-pwned-passwords-privacy-by-exclusively-supporting-anonymity/ */ - private function getRangeHash(string $passwordHash): string - { + private function getRangeHash( + #[SensitiveParameter] + string $passwordHash + ): string { return substr($passwordHash, self::HIBP_K_ANONYMITY_HASH_RANGE_BASE, self::HIBP_K_ANONYMITY_HASH_RANGE_LENGTH); } @@ -99,8 +108,10 @@ private function getRangeHash(string $passwordHash): string * * @throws ClientExceptionInterface */ - private function retrieveHashList(string $passwordRange): string - { + private function retrieveHashList( + #[SensitiveParameter] + string $passwordRange + ): string { $request = $this->makeHttpRequest->createRequest( 'GET', self::HIBP_API_URI . '/range/' . $passwordRange @@ -113,8 +124,12 @@ private function retrieveHashList(string $passwordRange): string /** * Checks if the password is in the response from HIBP */ - private function hashInResponse(string $sha1Hash, string $resultStream): bool - { + private function hashInResponse( + #[SensitiveParameter] + string $sha1Hash, + #[SensitiveParameter] + string $resultStream + ): bool { $data = explode("\r\n", $resultStream); $hashes = array_filter($data, static function ($value) use ($sha1Hash): bool { [$hash] = explode(':', $value);