Question
Answer (97)
Problem
In internal/services/iam/server.go:handleSignup (line ~99), the only password validation is checking that it is non-empty after trimming:
func validSignupPayload(email, password, name, organizationName, organizationKind string) bool {
if strings.TrimSpace(email) == "" || strings.TrimSpace(password) == "" || strings.TrimSpace(name) == "" {
This means users can sign up with passwords like "a" or "1". For a platform handling financial transactions (invoices, settlements, credit decisions), this is a critical security gap. Attackers can trivially brute-force accounts.
Additionally, there is no email format validation — any non-empty string is accepted as an email address.
Files
internal/services/iam/server.go:handleSignup— missing password complexity checkinternal/services/iam/server.go:validSignupPayload— only checks non-emptyinternal/identity/store.go:CreateSignup(MemoryStore) — no validation at store level either
Suggested Fix
- Add password strength requirements (minimum 8 chars, at least one letter + one digit)
- Add basic email format validation (must contain
@with non-empty local and domain parts) - Consider adding these as package-level validation functions in
internal/identity/so both memory and postgres paths share them - Add tests for rejected weak passwords and malformed emails
func validatePassword(password string) error {
if len(password) < 8 {
return errors.New("password must be at least 8 characters")
}
var hasLetter, hasDigit bool
for _, c := range password {
if unicode.IsLetter(c) { hasLetter = true }
if unicode.IsDigit(c) { hasDigit = true }
}
if !hasLetter || !hasDigit {
return errors.New("password must contain at least one letter and one digit")
}
return nil
}
Priority
P0 — Direct financial platform security risk. Weak credentials enable account takeover.
Problem:
In internal/services/iam/server.go:handleSignup (line ~99), the password validation is only checking that it is non-empty after trimming. This means users can sign up with weak passwords like "a" or "1". For a financial platform handling transactions (invoices, settlements, credit decisions), this is a critical security gap. Attackers can easily brute-force accounts. Additionally, there is no email format validation in place, allowing any non-empty string to be accepted as an email address.
Files:
internal/services/iam/server.go:handleSignup: missing password complexity checkinternal/services/iam/server.go:validSignupPayload: only checks non-emptyinternal/identity/store.go:CreateSignup(MemoryStore): no validation at store level either
Suggested Fix:
- Add password strength requirements (minimum 8 characters, at least one letter + one digit)
- Add basic email format validation (must contain `@` with non-empty local and domain parts)
- Consider adding these as package-level validation functions in `internal/identity/` so both memory and postgres paths share them
- Add tests for rejected weak passwords and malformed emails
func validatePassword(password string) error {
if len(password) < 8 {
return errors.New("password must be at least 8 characters")
}
var hasLetter, hasDigit bool
for _, c := range password {
if unicode.IsLetter(c) { hasLetter = true }
if unicode.IsDigit(c) { hasDigit = true }
}
if !hasLetter || !hasDigit {
return errors.New("password must contain at least one letter and one digit")
}
return nil
}
Priority:
P0: Direct financial platform security risk. Weak credentials enable account takeover.
Answer:
Problem:
The problem lies in internal/services/iam/server.go:handleSignup (line ~99), where password validation is only checking for an empty password. This results in weak passwords, such as "a" and "1", being accepted during the sign-up process. Given the financial nature of the platform, handling transactions (invoices, settlements, credit decisions), this security gap poses a significant risk. Furthermore, email format validation is missing, allowing any non-empty string to be accepted as an email address.
Files:
internal/services/iam/server.go:handleSignup: missing password complexity checkinternal/services/iam/server.go:validSignupPayload: only checks non-emptyinternal/identity/store.go:CreateSignup(MemoryStore): no validation at store level either
Suggested Fix:
- Add password strength requirements (minimum 8 characters, at least one letter + one digit)
- Add basic email format validation (must contain `@` with non-empty local and domain parts)
- Consider adding these as package-level validation functions in `internal/identity/` so both memory and postgres paths share them
- Add tests for rejected weak passwords and malformed emails
func validatePassword(password string) error {
if len(password) < 8 {
return errors.New("password must be at least 8 characters")
}
var hasLetter, hasDigit bool
for _, c := range password {
if unicode.IsLetter(c) { hasLetter = true }
if unicode.IsDigit(c) { hasDigit = true }
}
if !hasLetter || !hasDigit {
return errors.New("password must contain at least one letter and one digit")
}
return nil
}
Priority:
P0: This is a high-priority issue as it poses a direct security risk to the financial platform due to weak credentials enabling account takeover.