[bugfix] Change maximumPasswordLength to 72 bytes (#2012)

This commit is contained in:
tobi 2023-07-21 11:29:18 +02:00 committed by GitHub
parent 95e2024c2a
commit d6fa74e5dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 18 deletions

View file

@ -21,7 +21,6 @@
"errors" "errors"
"fmt" "fmt"
"net/mail" "net/mail"
"strings"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
@ -32,8 +31,8 @@
) )
const ( const (
maximumPasswordLength = 256 maximumPasswordLength = 72 // 72 bytes is the maximum length afforded by bcrypt. See https://pkg.go.dev/golang.org/x/crypto/bcrypt#GenerateFromPassword.
minimumPasswordEntropy = 60 // dictates password strength. See https://github.com/wagslane/go-password-validator minimumPasswordEntropy = 60 // Heuristic for password strength. See https://github.com/wagslane/go-password-validator.
minimumReasonLength = 40 minimumReasonLength = 40
maximumReasonLength = 500 maximumReasonLength = 500
maximumSiteTitleLength = 40 maximumSiteTitleLength = 40
@ -47,23 +46,29 @@
maximumListTitleLength = 200 maximumListTitleLength = 200
) )
// NewPassword returns an error if the given password is not sufficiently strong, or nil if it's ok. // NewPassword returns a helpful error if the given password
// is too short, too long, or not sufficiently strong.
func NewPassword(password string) error { func NewPassword(password string) error {
if password == "" { // Ensure length is OK first.
return errors.New("no password provided") if pwLen := len(password); pwLen == 0 {
} return errors.New("no password provided / provided password was 0 bytes")
} else if pwLen > maximumPasswordLength {
if len([]rune(password)) > maximumPasswordLength { return fmt.Errorf(
return fmt.Errorf("password should be no more than %d chars", maximumPasswordLength) "password should be no more than %d bytes, provided password was %d bytes",
maximumPasswordLength, pwLen,
)
} }
if err := pwv.Validate(password, minimumPasswordEntropy); err != nil { if err := pwv.Validate(password, minimumPasswordEntropy); err != nil {
// Modify error message to include percentage requred entropy the password has // Calculate the percentage of our desired entropy this password fulfils.
percent := int(100 * pwv.GetEntropy(password) / minimumPasswordEntropy) entropyPercent := int(100 * pwv.GetEntropy(password) / minimumPasswordEntropy)
return errors.New(strings.ReplaceAll(
err.Error(), // Replace the first 17 bytes (`insecure password`)
"insecure password", // of the error string with our own entropy message.
fmt.Sprintf("password is only %d%% strength", percent))) entropyMsg := fmt.Sprintf("password is only %d%% strength", entropyPercent)
errMsg := entropyMsg + err.Error()[17:]
return errors.New(errMsg)
} }
return nil // password OK return nil // password OK

View file

@ -45,7 +45,7 @@ func (suite *ValidationTestSuite) TestCheckPasswordStrength() {
err = validate.NewPassword(empty) err = validate.NewPassword(empty)
if suite.Error(err) { if suite.Error(err) {
suite.Equal(errors.New("no password provided"), err) suite.Equal(errors.New("no password provided / provided password was 0 bytes"), err)
} }
err = validate.NewPassword(terriblePassword) err = validate.NewPassword(terriblePassword)
@ -75,7 +75,7 @@ func (suite *ValidationTestSuite) TestCheckPasswordStrength() {
err = validate.NewPassword(tooLong) err = validate.NewPassword(tooLong)
if suite.Error(err) { if suite.Error(err) {
suite.Equal(errors.New("password should be no more than 256 chars"), err) suite.Equal(errors.New("password should be no more than 72 bytes, provided password was 571 bytes"), err)
} }
err = validate.NewPassword(strongPassword) err = validate.NewPassword(strongPassword)