Skip to content

Commit

Permalink
[10.x] Verify hash config (#48814)
Browse files Browse the repository at this point in the history
* Verify hash config

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
timacdonald and taylorotwell committed Oct 25, 2023
1 parent 38e7183 commit 98ffb75
Show file tree
Hide file tree
Showing 5 changed files with 379 additions and 34 deletions.
15 changes: 14 additions & 1 deletion src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use ReflectionClass;
use ReflectionMethod;
use ReflectionNamedType;
use RuntimeException;

trait HasAttributes
{
Expand Down Expand Up @@ -1316,7 +1317,19 @@ public static function encryptUsing($encrypter)
*/
protected function castAttributeAsHashedString($key, $value)
{
return $value !== null && ! Hash::isHashed($value) ? Hash::make($value) : $value;
if ($value === null) {
return null;
}

if (! Hash::isHashed($value)) {
return Hash::make($value);
}

if (! Hash::verifyConfiguration($value)) {
throw new RuntimeException("Could not verify the hashed value's configuration.");
}

return $value;
}

/**
Expand Down
13 changes: 12 additions & 1 deletion src/Illuminate/Hashing/Argon2IdHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Argon2IdHasher extends ArgonHasher
*/
public function check($value, $hashedValue, array $options = [])
{
if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'argon2id') {
if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) {
throw new RuntimeException('This password does not use the Argon2id algorithm.');
}

Expand All @@ -29,6 +29,17 @@ public function check($value, $hashedValue, array $options = [])
return password_verify($value, $hashedValue);
}

/**
* Verify the hashed value's algorithm.
*
* @param string $hashedValue
* @return bool
*/
protected function isUsingCorrectAlgorithm($hashedValue)
{
return $this->info($hashedValue)['algoName'] === 'argon2id';
}

/**
* Get the algorithm that should be used for hashing.
*
Expand Down
52 changes: 51 additions & 1 deletion src/Illuminate/Hashing/ArgonHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ protected function algorithm()
*/
public function check($value, $hashedValue, array $options = [])
{
if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'argon2i') {
if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) {
throw new RuntimeException('This password does not use the Argon2i algorithm.');
}

Expand All @@ -118,6 +118,56 @@ public function needsRehash($hashedValue, array $options = [])
]);
}

/**
* Verifies that the configuration is less than or equal to what is configured.
*
* @internal
*/
public function verifyConfiguration($value)
{
return $this->isUsingCorrectAlgorithm($value) && $this->isUsingValidOptions($value);
}

/**
* Verify the hashed value's algorithm.
*
* @param string $hashedValue
* @return bool
*/
protected function isUsingCorrectAlgorithm($hashedValue)
{
return $this->info($hashedValue)['algoName'] === 'argon2i';
}

/**
* Verify the hashed value's options.
*
* @param string $hashedValue
* @return bool
*/
protected function isUsingValidOptions($hashedValue)
{
['options' => $options] = $this->info($hashedValue);

if (
! is_int($options['memory_cost'] ?? null) ||
! is_int($options['time_cost'] ?? null) ||
! is_int($options['threads'] ?? null)
) {
return false;
}

if (
$options['memory_cost'] > $this->memory ||
$options['time_cost'] > $this->time ||
$options['threads'] > $this->threads
) {
return false;
}

return true;
}

/**
* Set the default password memory factor.
*
Expand Down
44 changes: 43 additions & 1 deletion src/Illuminate/Hashing/BcryptHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function make($value, array $options = [])
*/
public function check($value, $hashedValue, array $options = [])
{
if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'bcrypt') {
if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) {
throw new RuntimeException('This password does not use the Bcrypt algorithm.');
}

Expand All @@ -88,6 +88,48 @@ public function needsRehash($hashedValue, array $options = [])
]);
}

/**
* Verifies that the configuration is less than or equal to what is configured.
*
* @internal
*/
public function verifyConfiguration($value)
{
return $this->isUsingCorrectAlgorithm($value) && $this->isUsingValidOptions($value);
}

/**
* Verify the hashed value's algorithm.
*
* @param string $hashedValue
* @return bool
*/
protected function isUsingCorrectAlgorithm($hashedValue)
{
return $this->info($hashedValue)['algoName'] === 'bcrypt';
}

/**
* Verify the hashed value's options.
*
* @param string $hashedValue
* @return bool
*/
protected function isUsingValidOptions($hashedValue)
{
['options' => $options] = $this->info($hashedValue);

if (! is_int($options['cost'] ?? null)) {
return false;
}

if ($options['cost'] > $this->rounds) {
return false;
}

return true;
}

/**
* Set the default password work factor.
*
Expand Down
Loading

0 comments on commit 98ffb75

Please sign in to comment.