Weak Password Requirements in answerdev/answer
Description
Weak Password Requirements in GitHub repository answerdev/answer prior to v1.1.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Weak password requirements in Answer before v1.1.0 allow users to set easily guessed passwords, increasing brute-force risk.
Vulnerability
Overview CVE-2023-4125 describes a weak password requirement in the Answer Q&A platform prior to version 1.1.0. The software lacked sufficient password complexity rules, permitting users to create passwords that were likely weak and easily guessable [2]. This deficiency in password policy enforcement directly undermined account security.
Exploitation
Prerequisites An attacker can exploit this vulnerability remotely without authentication by simply registering a new account with a weak password or by enumerating existing accounts that have weak passwords [1]. The attack surface includes any public-facing instance of Answer that allows user registration. No special network position is required beyond ordinary internet access.
Impact
Successful exploitation allows an attacker to compromise user accounts through brute-force or dictionary attacks against the permitted weak passwords [2]. Gaining access to an account could lead to unauthorized viewing, posting, or modification of content within the Q&A platform, potentially including sensitive data shared in private or internal sites.
Mitigation
The vulnerability is patched in Answer v1.1.0, which introduced stronger password validation, including rejecting spaces in passwords [1]. Administrators are advised to update to the latest version immediately. There is no known workaround besides applying the patch.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/answerdev/answerGo | < 1.1.0 | 1.1.0 |
Affected products
2- answerdev/answerdev/answerv5Range: unspecified
Patches
17d23b17cdbbefix(password): password can't contains space.
6 files changed · +36 −50
i18n/en_US.yaml+3 −15 modified@@ -1,19 +1,4 @@ # The following fields are used for back-end -# backend.email.tpl.change_email.title.other = Confirm your new email address for {{.SiteName}} by clicking on the following link:\u003cbr\u003e\u003cbr\u003e\n\n\u003ca href='{{.ChangeEmailUrl}}' target='_blank'\u003e{{.ChangeEmailUrl}}\u003c/a\u003e\u003cbr\u003e\u003cbr\u003e\n\nIf you did not request this change, please ignore this email.\n -# backend.email.tpl.change_email.body.other = [{{.SiteName}}] Confirm your new email address -# backend.email.tpl.new_answer.title.other = \u003cstrong\u003e\u003ca href='{{.AnswerUrl}}'\u003e{{.QuestionTitle}}\u003c/a\u003e\u003c/strong\u003e\u003cbr\u003e\u003cbr\u003e\n\n\u003csmall\u003e{{.DisplayName}}:\u003c/small\u003e\u003cbr\u003e\n\u003cblockquote\u003e{{.AnswerSummary}}\u003c/blockquote\u003e\u003cbr\u003e\n\u003ca href='{{.AnswerUrl}}'\u003eView it on {{.SiteName}}\u003c/a\u003e\u003cbr\u003e\u003cbr\u003e\n\n\u003csmall\u003eYou are receiving this because you authored the thread. \u003ca href='{{.UnsubscribeUrl}}'\u003eUnsubscribe\u003c/a\u003e\u003c/small\u003e -# backend.email.tpl.new_answer.body.other = [{{.SiteName}}] {{.DisplayName}} answered your question -# backend.email.tpl.new_comment.title.other = \u003cstrong\u003e\u003ca href='{{.CommentUrl}}'\u003e{{.QuestionTitle}}\u003c/a\u003e\u003c/strong\u003e\u003cbr\u003e\u003cbr\u003e\n\n\u003csmall\u003e{{.DisplayName}}:\u003c/small\u003e\u003cbr\u003e\n\u003cblockquote\u003e{{.CommentSummary}}\u003c/blockquote\u003e\u003cbr\u003e\n\u003ca href='{{.CommentUrl}}'\u003eView it on {{.SiteName}}\u003c/a\u003e\u003cbr\u003e\u003cbr\u003e\n\n\u003csmall\u003eYou are receiving this because you authored the thread. \u003ca href='{{.UnsubscribeUrl}}'\u003eUnsubscribe\u003c/a\u003e\u003c/small\u003e -# backend.email.tpl.new_comment.body.other = [{{.SiteName}}] {{.DisplayName}} commented on your post -# backend.email.tpl.pass_reset.title.other = Somebody asked to reset your password on [{{.SiteName}}].\u003cbr\u003e\u003cbr\u003e\n\nIf it was not you, you can safely ignore this email.\u003cbr\u003e\u003cbr\u003e\n\nClick the following link to choose a new password:\u003cbr\u003e\n\u003ca href='{{.PassResetUrl}}' target='_blank'\u003e{{.PassResetUrl}}\u003c/a\u003e\n -# backend.email.tpl.pass_reset.body.other = [{{.SiteName }}] Password reset -# backend.email.tpl.register.title.other = Welcome to {{.SiteName}}\u003cbr\u003e\u003cbr\u003e\n\nClick the following link to confirm and activate your new account:\u003cbr\u003e\n\u003ca href='{{.RegisterUrl}}' target='_blank'\u003e{{.RegisterUrl}}\u003c/a\u003e\u003cbr\u003e\u003cbr\u003e\n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n -# backend.email.tpl.register.body.other = [{{.SiteName}}] Confirm your new account -# backend.email.tpl.test.title.other = This is a test email. -# backend.email.tpl.test.body.other = [{{.SiteName}}] Test Email - - - backend: base: success: @@ -123,6 +108,9 @@ backend: email_or_password_wrong_error: other: Email and password do not match. error: + password: + space_invalid: + other: Password cannot contain spaces. admin: cannot_update_their_password: other: You cannot modify your password.
i18n/zh_CN.yaml+4 −1 modified@@ -97,13 +97,16 @@ backend: other: 编辑标签描述(无需审核) rank_tag_synonym_label: other: 管理标签同义词 - email: + e_mail: other: 邮箱 password: other: 密码 email_or_password_wrong_error: other: 邮箱和密码不匹配。 error: + password: + space_invalid: + other: 密码不能包含空格。 admin: cannot_update_their_password: other: 您无法修改自己的密码。
internal/base/validator/validator.go+3 −1 modified@@ -207,10 +207,12 @@ func (m *MyValidator) Check(value interface{}) (errFields []*FormErrorField, err if err == nil { return nil, nil } + errMsg := "" for _, errField := range errFields { errField.ErrorMsg = translator.Tr(m.Lang, errField.ErrorMsg) + errMsg = errField.ErrorMsg } - return errFields, err + return errFields, myErrors.BadRequest(reason.RequestFormatError).WithMsg(errMsg) } return nil, nil }
internal/migrations/v10.go+2 −0 modified@@ -24,6 +24,8 @@ func addLoginLimitations(x *xorm.Engine) error { _ = json.Unmarshal([]byte(loginSiteInfo.Content), content) content.AllowEmailRegistrations = true content.AllowEmailDomains = make([]string, 0) + data, _ := json.Marshal(content) + loginSiteInfo.Content = string(data) _, err = x.ID(loginSiteInfo.ID).Cols("content").Update(loginSiteInfo) if err != nil { return fmt.Errorf("update site info failed: %w", err)
internal/schema/user_schema.go+11 −20 modified@@ -262,35 +262,29 @@ type UserRegisterReq struct { } func (u *UserRegisterReq) Check() (errFields []*validator.FormErrorField, err error) { - // TODO i18n - err = checker.CheckPassword(8, 32, 0, u.Pass) - if err != nil { - errField := &validator.FormErrorField{ + if err = checker.CheckPassword(u.Pass); err != nil { + errFields = append(errFields, &validator.FormErrorField{ ErrorField: "pass", ErrorMsg: err.Error(), - } - errFields = append(errFields, errField) + }) return errFields, err } return nil, nil } type UserModifyPasswordReq struct { - OldPass string `validate:"omitempty,gte=8,lte=32" json:"old_pass"` - Pass string `validate:"required,gte=8,lte=32" json:"pass"` + OldPass string `validate:"omitempty,gte=8,lte=32" json:"old_pass"` + Pass string `validate:"required,gte=8,lte=32" json:"pass"` UserID string `json:"-"` AccessToken string `json:"-"` } func (u *UserModifyPasswordReq) Check() (errFields []*validator.FormErrorField, err error) { - // TODO i18n - err = checker.CheckPassword(8, 32, 0, u.Pass) - if err != nil { - errField := &validator.FormErrorField{ + if err = checker.CheckPassword(u.Pass); err != nil { + errFields = append(errFields, &validator.FormErrorField{ ErrorField: "pass", ErrorMsg: err.Error(), - } - errFields = append(errFields, errField) + }) return errFields, err } return nil, nil @@ -352,14 +346,11 @@ type UserRePassWordRequest struct { } func (u *UserRePassWordRequest) Check() (errFields []*validator.FormErrorField, err error) { - // TODO i18n - err = checker.CheckPassword(8, 32, 0, u.Pass) - if err != nil { - errField := &validator.FormErrorField{ + if err = checker.CheckPassword(u.Pass); err != nil { + errFields = append(errFields, &validator.FormErrorField{ ErrorField: "pass", ErrorMsg: err.Error(), - } - errFields = append(errFields, errField) + }) return errFields, err } return nil, nil
pkg/checker/password.go+13 −13 modified@@ -3,6 +3,7 @@ package checker import ( "fmt" "regexp" + "strings" ) const ( @@ -13,27 +14,26 @@ const ( LevelS ) -// CheckPassword -// minLength: Specifies the minimum length of a password -// maxLength:Specifies the maximum length of a password -// minLevel:Specifies the minimum strength level required for passwords -// pwd:Text passwords -func CheckPassword(minLength, maxLength, minLevel int, pwd string) error { - // First check whether the password length is within the range - if len(pwd) < minLength { - return fmt.Errorf("BAD PASSWORD: The password is shorter than %d characters", minLength) - } - if len(pwd) > maxLength { - return fmt.Errorf("BAD PASSWORD: The password is logner than %d characters", maxLength) +const ( + PasswordCannotContainSpaces = "error.password.space_invalid" +) + +// CheckPassword checks the password strength +func CheckPassword(password string) error { + if strings.Contains(password, " ") { + return fmt.Errorf(PasswordCannotContainSpaces) } + // TODO Currently there is no requirement for password strength + minLevel := 0 + // The password strength level is initialized to D. // The regular is used to verify the password strength. // If the matching is successful, the password strength increases by 1 level := levelD patternList := []string{`[0-9]+`, `[a-z]+`, `[A-Z]+`, `[~!@#$%^&*?_-]+`} for _, pattern := range patternList { - match, _ := regexp.MatchString(pattern, pwd) + match, _ := regexp.MatchString(pattern, password) if match { level++ }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.