Moderate severityNVD Advisory· Published Jun 30, 2025· Updated Aug 4, 2025
File Browser Insecurely Handles Passwords
CVE-2025-52997
Description
File Browser provides a file managing interface within a specified directory and it can be used to upload, delete, preview, rename and edit files. Prior to version 2.34.1, a missing password policy and brute-force protection makes the authentication process insecure. Attackers could mount a brute-force attack to retrieve the passwords of all accounts in a given instance. This issue has been patched in version 2.34.1.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/filebrowser/filebrowser/v2Go | < 2.34.1 | 2.34.1 |
github.com/filebrowser/filebrowserGo | <= 1.11.0 | — |
Affected products
1- Range: < 2.34.1
Patches
1bf37f88c3222fix: passthrough the minimum password length (#5236)
11 files changed · +100065 −30
auth/hook.go+2 −2 modified@@ -150,7 +150,7 @@ func (a *HookAuth) SaveUser() (*users.User, error) { } if u == nil { - pass, err := users.HashAndValidatePwd(a.Cred.Password, a.Settings.MinimumPasswordLength) + pass, err := users.ValidateAndHashPwd(a.Cred.Password, a.Settings.MinimumPasswordLength) if err != nil { return nil, err } @@ -186,7 +186,7 @@ func (a *HookAuth) SaveUser() (*users.User, error) { // update the password when it doesn't match the current if p { - pass, err := users.HashAndValidatePwd(a.Cred.Password, a.Settings.MinimumPasswordLength) + pass, err := users.ValidateAndHashPwd(a.Cred.Password, a.Settings.MinimumPasswordLength) if err != nil { return nil, err }
auth/proxy.go+1 −1 modified@@ -35,7 +35,7 @@ func (a ProxyAuth) createUser(usr users.Store, setting *settings.Settings, srv * } var hashedRandomPassword string - hashedRandomPassword, err = users.HashAndValidatePwd(pwd, setting.MinimumPasswordLength) + hashedRandomPassword, err = users.ValidateAndHashPwd(pwd, setting.MinimumPasswordLength) if err != nil { return nil, err }
cmd/root.go+1 −1 modified@@ -432,7 +432,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) { log.Println("Randomly generated password for user 'admin':", pwd) - password, err = users.HashAndValidatePwd(pwd, set.MinimumPasswordLength) + password, err = users.ValidateAndHashPwd(pwd, set.MinimumPasswordLength) checkErr(err) }
cmd/users_add.go+1 −1 modified@@ -21,7 +21,7 @@ var usersAddCmd = &cobra.Command{ checkErr(err) getUserDefaults(cmd.Flags(), &s.Defaults, false) - password, err := users.HashAndValidatePwd(args[1], s.MinimumPasswordLength) + password, err := users.ValidateAndHashPwd(args[1], s.MinimumPasswordLength) checkErr(err) user := &users.User{
cmd/users_update.go+1 −1 modified@@ -66,7 +66,7 @@ options you want to change.`, } if password != "" { - user.Password, err = users.HashAndValidatePwd(password, s.MinimumPasswordLength) + user.Password, err = users.ValidateAndHashPwd(password, s.MinimumPasswordLength) checkErr(err) }
errors/errors.go+13 −2 modified@@ -1,13 +1,16 @@ package errors -import "errors" +import ( + "errors" + "fmt" +) var ( ErrEmptyKey = errors.New("empty key") ErrExist = errors.New("the resource already exists") ErrNotExist = errors.New("the resource does not exist") ErrEmptyPassword = errors.New("password is empty") - ErrShortPassword = errors.New("password is too short") + ErrEasyPassword = errors.New("password is too easy") ErrEmptyUsername = errors.New("username is empty") ErrEmptyRequest = errors.New("empty request") ErrScopeIsRelative = errors.New("scope is a relative path") @@ -20,3 +23,11 @@ var ( ErrSourceIsParent = errors.New("source is parent") ErrRootUserDeletion = errors.New("user with id 1 can't be deleted") ) + +type ErrShortPassword struct { + MinimumLength uint +} + +func (e ErrShortPassword) Error() string { + return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength) +}
http/auth.go+2 −2 modified@@ -151,9 +151,9 @@ var signupHandler = func(_ http.ResponseWriter, r *http.Request, d *data) (int, d.settings.Defaults.Apply(user) - pwd, err := users.HashAndValidatePwd(info.Password, d.settings.MinimumPasswordLength) + pwd, err := users.ValidateAndHashPwd(info.Password, d.settings.MinimumPasswordLength) if err != nil { - return http.StatusInternalServerError, err + return http.StatusBadRequest, err } user.Password = pwd
http/users.go+11 −17 modified@@ -125,13 +125,9 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d * return http.StatusBadRequest, fbErrors.ErrEmptyPassword } - if len(req.Data.Password) < int(d.settings.MinimumPasswordLength) { - return http.StatusBadRequest, fbErrors.ErrShortPassword - } - - req.Data.Password, err = users.HashAndValidatePwd(req.Data.Password, d.settings.MinimumPasswordLength) + req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength) if err != nil { - return http.StatusInternalServerError, err + return http.StatusBadRequest, err } userHome, err := d.settings.MakeUserDir(req.Data.Username, req.Data.Scope, d.server.Root) @@ -167,17 +163,19 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request } if req.Data.Password != "" { - req.Data.Password, err = users.HashAndValidatePwd(req.Data.Password, d.settings.MinimumPasswordLength) + req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength) + if err != nil { + return http.StatusBadRequest, err + } } else { var suser *users.User suser, err = d.store.Users.Get(d.server.Root, d.raw.(uint)) + if err != nil { + return http.StatusInternalServerError, err + } req.Data.Password = suser.Password } - if err != nil { - return http.StatusInternalServerError, err - } - req.Which = []string{} } @@ -190,13 +188,9 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request return http.StatusForbidden, nil } - if len(req.Data.Password) < int(d.settings.MinimumPasswordLength) { - return http.StatusBadRequest, fbErrors.ErrShortPassword - } - - req.Data.Password, err = users.HashAndValidatePwd(req.Data.Password, d.settings.MinimumPasswordLength) + req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength) if err != nil { - return http.StatusInternalServerError, err + return http.StatusBadRequest, err } }
users/assets/common-passwords.txt+100000 −0 addedusers/assets.go+26 −0 added@@ -0,0 +1,26 @@ +package users + +import ( + "embed" + "strings" +) + +//go:embed assets +var assets embed.FS +var commonPasswords map[string]struct{} + +//nolint:gochecknoinits +func init() { + // Password list sourced from: + // https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/100k-most-used-passwords-NCSC.txt + data, err := assets.ReadFile("assets/common-passwords.txt") + if err != nil { + panic(err) + } + + passwords := strings.Split(strings.TrimSpace(string(data)), "\n") + commonPasswords = make(map[string]struct{}, len(passwords)) + for _, password := range passwords { + commonPasswords[strings.TrimSpace(password)] = struct{}{} + } +}
users/password.go+7 −3 modified@@ -9,10 +9,14 @@ import ( fbErrors "github.com/filebrowser/filebrowser/v2/errors" ) -// HashPwd hashes a password. -func HashAndValidatePwd(password string, minimumLength uint) (string, error) { +// ValidateAndHashPwd validates and hashes a password. +func ValidateAndHashPwd(password string, minimumLength uint) (string, error) { if uint(len(password)) < minimumLength { - return "", fbErrors.ErrShortPassword + return "", fbErrors.ErrShortPassword{MinimumLength: minimumLength} + } + + if _, ok := commonPasswords[password]; ok { + return "", fbErrors.ErrEasyPassword } return HashPwd(password)
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-cm2r-rg7r-p7ggghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-52997ghsaADVISORY
- github.com/filebrowser/filebrowser/commit/bf37f88c32222ad9c186482bb97338a9c9b4a93cghsax_refsource_MISCWEB
- github.com/filebrowser/filebrowser/security/advisories/GHSA-cm2r-rg7r-p7ggghsax_refsource_CONFIRMWEB
- github.com/sbaresearch/advisories/tree/public/2025/SBA-ADV-20250327-01_Filebrowser_Insecure_Password_Handlingghsax_refsource_MISCWEB
- pkg.go.dev/vuln/GO-2025-3792ghsaWEB
News mentions
0No linked articles in our index yet.