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 1/3] 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); From 506e992b582844e8c70998cfa3444c8940f8e1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 13 Dec 2022 23:07:29 +0100 Subject: [PATCH 2/3] Add #[\SensitiveParameter] attribute to CreditCard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Credit Card numbers are generally considered to be sensitive. Signed-off-by: Tim Düsterhus --- src/CreditCard.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/CreditCard.php b/src/CreditCard.php index baa385bfc..4b7326307 100644 --- a/src/CreditCard.php +++ b/src/CreditCard.php @@ -5,6 +5,7 @@ use Exception; use Laminas\Stdlib\ArrayUtils; use Laminas\Validator\Exception\InvalidArgumentException; +use SensitiveParameter; use Traversable; use function array_key_exists; @@ -361,8 +362,10 @@ public function setService($service) * @param string $value * @return bool */ - public function isValid($value) - { + public function isValid( + #[SensitiveParameter] + $value + ) { $this->setValue($value); if (! is_string($value)) { From 278c5db3c49ebf26a339274e6c3d5c5ef0ab0279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 13 Dec 2022 23:20:27 +0100 Subject: [PATCH 3/3] Suppress buggy code style check for parameter attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Düsterhus --- src/CreditCard.php | 5 +++++ src/UndisclosedPassword.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/CreditCard.php b/src/CreditCard.php index 4b7326307..bb5faa9af 100644 --- a/src/CreditCard.php +++ b/src/CreditCard.php @@ -356,6 +356,9 @@ public function setService($service) return $this; } + // The following rule is buggy for parameters attributes + // phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing.NoSpaceBetweenTypeHintAndParameter + /** * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum) * @@ -436,4 +439,6 @@ public function isValid( return true; } + + // phpcs:enable SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing.NoSpaceBetweenTypeHintAndParameter } diff --git a/src/UndisclosedPassword.php b/src/UndisclosedPassword.php index 8fd508df6..ab0aa534d 100644 --- a/src/UndisclosedPassword.php +++ b/src/UndisclosedPassword.php @@ -46,6 +46,9 @@ public function __construct(private ClientInterface $httpClient, private Request parent::__construct(); } + // The following rule is buggy for parameters attributes + // phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing.NoSpaceBetweenTypeHintAndParameter + /** {@inheritDoc} */ public function isValid( #[SensitiveParameter] @@ -64,6 +67,8 @@ public function isValid( return true; } + // phpcs:enable SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing.NoSpaceBetweenTypeHintAndParameter + private function isPwnedPassword( #[SensitiveParameter] string $password