-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request from GHSA-c5vj-f36q-p9vg
* feat: copy the current methods as depreacted * fix: password shucking * feat: support old dangerous passwords * docs: add Upgrade Guide * refactor: fix variable name typo Co-authored-by: MGatner <[email protected]> * refactor: fix variable name typo * fix: $options is missing for password_needs_rehash() * docs: add OWASP Cheat Sheet in README * docs: add explanation in UPGRADING.md * docs: replace Config/Auth.php with app/Config/Auth.php * docs: add How to Strengthen the Password * docs: UPGRADING.md * docs: add note in "Minimum Password Length" * docs: $supportOldDangerousPassword will be removed in v1.0.0 * feat: add validation rule for max password length PASSWORD_BCRYPT -> 72 bytes Others -> 255 characters * docs: update docs * feat: add new lang item to new lang files * feat: add errorPasswordTooLongBytes to Language/pt-BR * refactor: ChangeIfElseValueAssignToEarlyReturnRector --------- Co-authored-by: MGatner <[email protected]>
- Loading branch information
Showing
26 changed files
with
435 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Upgrade Guide | ||
|
||
## Version 1.0.0-beta.3 to 1.0.0-beta.4 | ||
|
||
### Important Password Changes | ||
|
||
#### Password Incompatibility | ||
|
||
Shield 1.0.0-beta.4 fixes a [vulnerability related to password storage](https://github.com/codeigniter4/shield/security/advisories/GHSA-c5vj-f36q-p9vg). | ||
As a result, hashed passwords already stored in the database are no longer compatible | ||
and cannot be used by default. | ||
|
||
All hashed passwords stored in Shield v1.0.0-beta.3 or earlier are easier to | ||
crack than expected due to the above vulnerability. Therefore, they should be | ||
removed as soon as possible. | ||
|
||
Existing users will no longer be able to log in with their passwords and will | ||
need to log in with the magic link and then set their passwords again. | ||
|
||
#### If You Want to Allow Login with Existing Passwords | ||
|
||
If you want to use passwords saved in Shield v1.0.0-beta.3 or earlier, | ||
you must add the following property in `app/Config/Auth.php`: | ||
|
||
```php | ||
public bool $supportOldDangerousPassword = true; | ||
``` | ||
|
||
After upgrading, with the above setting, once a user logs in with the password, | ||
the hashed password is updated and stored in the database. | ||
|
||
In this case, the existing hashed passwords are still easier to crack than expected. | ||
Therefore, this setting should not be used for an extended period of time. | ||
So you should change the setting to `false` as soon as possible, and remove old | ||
hashed password. | ||
|
||
> **Note** | ||
> | ||
> This setting is deprecated. It will be removed in v1.0.0 official release. | ||
#### Limitations for the Default Password Handling | ||
|
||
By default, Shield uses the hashing algorithm `PASSWORD_DEFAULT` (see `app/Config/Auth.php`), | ||
that is, `PASSWORD_BCRYPT` at the time of writing. | ||
|
||
Now there are two limitations when you use `PASSWORD_BCRYPT`. | ||
|
||
1. the password will be truncated to a maximum length of 72 bytes. | ||
2. the password will be truncated at the first NULL byte (`\0`). | ||
|
||
If these behaviors are unacceptable, see [How to Strengthen the Password](https://github.com/codeigniter4/shield/blob/develop/docs/guides/strengthen_password.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# How to Strengthen the Password | ||
|
||
Shield allows you to customize password-related settings to make your passwords more secure. | ||
|
||
## Minimum Password Length | ||
|
||
The most important factor when it comes to passwords is the number of characters in the password. | ||
You can check password strength with [Password Strength Testing Tool](https://bitwarden.com/password-strength/). | ||
Short passwords may be cracked in less than one day. | ||
|
||
In Shield, you can set the users' minimum password length. The setting is | ||
`$minimumPasswordLength` in `app/Config/Auth.php`. The default value is 8 characters. | ||
It is the recommended minimum value by NIST. However, some organizations recommend | ||
12 to 14 characters. | ||
|
||
The longer the password, the stronger it is. Consider increasing the value. | ||
|
||
> **Note** | ||
> | ||
> This checking works when you validate passwords with the `strong_password` | ||
> validation rule. | ||
> | ||
> If you disable `CompositionValidator` (enabled by default) in `$passwordValidators`, | ||
> this checking will not work. | ||
## Password Hashing Algorithm | ||
|
||
You can change the password hashing algorithm by `$hashAlgorithm` in `app/Config/Auth.php`. | ||
The default value is `PASSWORD_DEFAULT` that is `PASSWORD_BCRYPT` at the time of writing. | ||
|
||
`PASSWORD_BCRYPT` means to create new password hashes using the bcrypt algorithm. | ||
|
||
You can use `PASSWORD_ARGON2ID` if your PHP has been compiled with Argon2 support. | ||
|
||
### PASSWORD_BCRYPT | ||
|
||
`PASSWORD_BCRYPT` has one configuration `$hashCost`. The bigger the cost, hashed passwords will be the stronger. | ||
|
||
You can find your appropriate cost with the following code: | ||
|
||
```php | ||
<?php | ||
/** | ||
* This code will benchmark your server to determine how high of a cost you can | ||
* afford. You want to set the highest cost that you can without slowing down | ||
* you server too much. 8-10 is a good baseline, and more is good if your servers | ||
* are fast enough. The code below aims for ≤ 50 milliseconds stretching time, | ||
* which is a good baseline for systems handling interactive logins. | ||
* | ||
* From: https://www.php.net/manual/en/function.password-hash.php#refsect1-function.password-hash-examples | ||
*/ | ||
$timeTarget = 0.05; // 50 milliseconds | ||
|
||
$cost = 8; | ||
do { | ||
$cost++; | ||
$start = microtime(true); | ||
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]); | ||
$end = microtime(true); | ||
} while (($end - $start) < $timeTarget); | ||
|
||
echo "Appropriate Cost Found: " . $cost; | ||
``` | ||
|
||
#### Limitations | ||
|
||
There are two limitations when you use `PASSWORD_BCRYPT`: | ||
|
||
1. the password will be truncated to a maximum length of 72 bytes. | ||
2. the password will be truncated at the first NULL byte (`\0`). | ||
|
||
##### 72 byte issue | ||
|
||
If a user submits a password longer than 72 bytes, the validation error will occur. | ||
If this behavior is unacceptable, consider: | ||
|
||
1. change the hashing algorithm to `PASSWORD_ARGON2ID`. It does not have such a limitation. | ||
|
||
##### NULL byte issue | ||
|
||
This is because `PASSWORD_BCRYPT` is not binary-safe. Normal users cannot | ||
send NULL bytes in a password string, so this is not a problem in most cases. | ||
|
||
But if this behavior is unacceptable, consider: | ||
|
||
1. adding a validation rule to prohibit NULL bytes or control codes. | ||
2. or change the hashing algorithm to `PASSWORD_ARGON2ID`. It is binary-safe. | ||
|
||
### PASSWORD_ARGON2ID | ||
|
||
`PASSWORD_ARGON2ID` has three configuration `$hashMemoryCost`, `$hashTimeCost`, | ||
and `$hashThreads`. | ||
|
||
If you use `PASSWORD_ARGON2ID`, you should use PHP's constants: | ||
|
||
```php | ||
public int $hashMemoryCost = PASSWORD_ARGON2_DEFAULT_MEMORY_COST; | ||
|
||
public int $hashTimeCost = PASSWORD_ARGON2_DEFAULT_TIME_COST; | ||
public int $hashThreads = PASSWORD_ARGON2_DEFAULT_THREADS; | ||
``` | ||
|
||
## Maximum Password Length | ||
|
||
By default, Shield has the validation rules for maximum password length. | ||
|
||
- 72 bytes for PASSWORD_BCRYPT | ||
- 255 characters for others | ||
|
||
You can customize the validation rule. See [Customizing Shield](../customization.md). | ||
|
||
## $supportOldDangerousPassword | ||
|
||
In `app/Config/Auth.php` there is `$supportOldDangerousPassword`, which is a | ||
setting for using passwords stored in older versions of Shield that were [vulnerable](https://github.com/codeigniter4/shield/security/advisories/GHSA-c5vj-f36q-p9vg). | ||
|
||
This setting is deprecated. If you have this setting set to `true`, you should change | ||
it to `false` as soon as possible, and remove old hashed password in your database. | ||
|
||
> **Note** | ||
> | ||
> This setting will be removed in v1.0.0 official release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,3 +51,4 @@ nav: | |
- Guides: | ||
- guides/api_tokens.md | ||
- guides/mobile_apps.md | ||
- guides/strengthen_password.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.