fix(iam): [P0] no password strength validation on signup — any single-character password accepted

Question

Grade: Education Subject: Keith-CY 1-tok
fix(iam): [P0] no password strength validation on signup — any single-character password accepted
Asked by:
97 Viewed 97 Answers

Answer (97)

Best Answer
(2297)

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 check
  • internal/services/iam/server.go:validSignupPayload — only checks non-empty
  • internal/identity/store.go:CreateSignup (MemoryStore) — no validation at store level either

Suggested Fix

  1. Add password strength requirements (minimum 8 chars, at least one letter + one digit)
  2. Add basic email format validation (must contain @ with non-empty local and domain parts)
  3. Consider adding these as package-level validation functions in internal/identity/ so both memory and postgres paths share them
  4. 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.

(4270)
**Answer:**

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 check
  • internal/services/iam/server.go:validSignupPayload: only checks non-empty
  • internal/identity/store.go:CreateSignup (MemoryStore): no validation at store level either

Suggested Fix:

  1. Add password strength requirements (minimum 8 characters, at least one letter + one digit)
  2. Add basic email format validation (must contain `@` with non-empty local and domain parts)
  3. Consider adding these as package-level validation functions in `internal/identity/` so both memory and postgres paths share them
  4. 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 check
  • internal/services/iam/server.go:validSignupPayload: only checks non-empty
  • internal/identity/store.go:CreateSignup (MemoryStore): no validation at store level either

Suggested Fix:

  1. Add password strength requirements (minimum 8 characters, at least one letter + one digit)
  2. Add basic email format validation (must contain `@` with non-empty local and domain parts)
  3. Consider adding these as package-level validation functions in `internal/identity/` so both memory and postgres paths share them
  4. 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.