diff --git a/cmd/serve.go b/cmd/serve.go index 87a9a6c9..8b5672cc 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -556,7 +556,7 @@ func parseUsers(usersRaw []string) ([]*user.User, error) { if !user.AllowedUsername(username) { return nil, fmt.Errorf("invalid auth-users: %s, username invalid", userLine) } else if err := user.ValidPasswordHash(passwordHash); err != nil { - return nil, fmt.Errorf("invalid auth-users: %s, %s", userLine, err.Error()) + return nil, fmt.Errorf("invalid auth-users: %s, password hash invalid, %s", userLine, err.Error()) } else if !user.AllowedRole(role) { return nil, fmt.Errorf("invalid auth-users: %s, role %s is not allowed, allowed roles are 'admin' or 'user'", userLine, role) } diff --git a/docs/config.md b/docs/config.md index 10640c46..f3a5e3a3 100644 --- a/docs/config.md +++ b/docs/config.md @@ -88,7 +88,7 @@ using Docker Compose (i.e. `docker-compose.yml`): NTFY_CACHE_FILE: /var/lib/ntfy/cache.db NTFY_AUTH_FILE: /var/lib/ntfy/auth.db NTFY_AUTH_DEFAULT_ACCESS: deny-all - NTFY_AUTH_USERS: 'phil:$2a$10$YLiO8U21sX1uhZamTLJXHuxgVC0Z/GKISibrKCLohPgtG7yIxSk4C:admin' + NTFY_AUTH_USERS: 'phil:$$2a$$10$$YLiO8U21sX1uhZamTLJXHuxgVC0Z/GKISibrKCLohPgtG7yIxSk4C:admin' # Must escape '$' as '$$' NTFY_BEHIND_PROXY: true NTFY_ATTACHMENT_CACHE_DIR: /var/lib/ntfy/attachments NTFY_ENABLE_LOGIN: true diff --git a/user/types.go b/user/types.go index 085f88fd..c65cb863 100644 --- a/user/types.go +++ b/user/types.go @@ -249,7 +249,8 @@ var ( ErrInvalidArgument = errors.New("invalid argument") ErrUserNotFound = errors.New("user not found") ErrUserExists = errors.New("user already exists") - ErrPasswordHashInvalid = errors.New("password hash but be a bcrypt hash, use 'ntfy user hash' to generate") + ErrPasswordHashInvalid = errors.New("password hash must be a bcrypt hash, use 'ntfy user hash' to generate") + ErrPasswordHashWeak = errors.New("password hash too weak, use 'ntfy user hash' to generate") ErrTierNotFound = errors.New("tier not found") ErrTokenNotFound = errors.New("token not found") ErrPhoneNumberNotFound = errors.New("phone number not found") diff --git a/user/util.go b/user/util.go index e0da4b27..2e425e19 100644 --- a/user/util.go +++ b/user/util.go @@ -45,6 +45,12 @@ func ValidPasswordHash(hash string) error { if !strings.HasPrefix(hash, "$2a$") && !strings.HasPrefix(hash, "$2b$") && !strings.HasPrefix(hash, "$2y$") { return ErrPasswordHashInvalid } + cost, err := bcrypt.Cost([]byte(hash)) + if err != nil { + return err + } else if cost < DefaultUserPasswordBcryptCost { + return ErrPasswordHashWeak + } return nil }