Skip to content

Signup: no server-side validation of identity fields (age, required, length, birthday format) #293

@rubin110

Description

@rubin110

Discovered during ad-hoc testing on PR #284. Full context in .claude/notes/2026-05-20-signup-flow-adhoc-findings.md — Finding 7 (non-username parts; the duplicate-username portion is fixed in commit 2fdbcd9 on PR #284).

signup_submit performs no validation on identity fields beyond CSRF. Every "Required" badge on the HTML form is required HTML5-attribute only.

Tested Result
No first_name → row created with first_name: null ✓ accepted
No last_name → row created with last_name: null ✓ accepted
Empty everything except email + csrf → row created with all-null identity ✓ accepted
Birthday in 2020 (5 years old) ✓ accepted, no age check
Birthday in 2030 (future) ✓ accepted
birthday=not-a-date ✓ accepted, stored verbatim
5000-char first_name ✓ accepted, no length cap

PS1 policy is members must be 18+. The admin portal validates this on identity edits via validate_age_18_or_older in FIELD_VALIDATORS, but signup does not.

Suggested approach

Mirror the admin portal's FIELD_VALIDATORS + validate_update_data pattern. Add a validate_signup_data() function in code/DHMemberPortal/app.py called near the top of signup_submit. Covers:

  • Required: first_name, last_name, email, birthday, username, phone
  • Length caps matching the HTML maxlength: 100 / 100 / (email) / (date) / 16 / 20
  • Birthday: ISO YYYY-MM-DD, strptime-parseable, member must be 18+ at signup time, not in the future, not before 1900
  • Phone: matches the existing client-side regex
  • Username: matches [a-zA-Z0-9_-]+, 3-16 chars

Incidentally closes Finding 6 (/signup/check-email bypass): once submit-time validation rejects malformed/missing fields, skipping the check-email step buys an attacker nothing.

Context: #283, PR #284

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions