Bound username length at creation (closes #184)
check / check (push) Successful in 5m15s

A login stores the username in the session cookie, which cannot carry
a value past about 4096 bytes, so a username of about 2 KB or more
could never log in and the login answered 500.

Usernames are now limited to 1024 bytes, about half of what the cookie
can carry. The User model rejects a longer one with
ErrUsernameTooLong, and a check constraint on the users table rejects
it for any path that bypasses the model. The comment on
MaxUsernameBytes gives the arithmetic.

Model: opus-5-5
This commit is contained in:
2026-09-29 08:35:29 +00:00
parent f0adeafde3
commit 41a1ecae8d
5 changed files with 153 additions and 16 deletions
+9 -9
View File
@@ -1472,7 +1472,7 @@ A registered user of the webhooker service.
| Field | Type | Description |
| ---------- | -------- | ----------- |
| `id` | UUID | Primary key |
| `username` | string | Unique login name |
| `username` | string | Unique login name, at most 1024 bytes so that it fits in the session cookie |
| `password` | string | Argon2id hash (never exposed via API) |
**Relations:** Has many Webhooks. Has many APIKeys.
@@ -2412,14 +2412,14 @@ Removing either cap fails 14 subtests.
`internal/middleware/logbound_test.go` and
`internal/handlers/logbound_test.go` drive 8 KB of client-chosen text
at each of these — 1 KB at `invalid password`, whose accounts are
shared with the successful-login line, where a username past 4 KB
overflows the session cookie and answers 500 before that line is
written — through both handlers, and through seven fills: plain text
as the baseline, and then the quotation mark, backslash, tab, newline,
C0 control and astral non-printable, six characters the wider of the
two handlers spends more on than the client spent sending them. Every
case holds each line to the 2,560-byte ceiling. That per-line ceiling
at each of these — just under 1 KB at `invalid password`, whose
accounts are shared with the successful-login line and so must stay
within the 1024-byte username limit — through both handlers, and
through seven fills: plain text as the baseline, and then the
quotation mark, backslash, tab, newline, C0 control and astral
non-printable, six characters the wider of the two handlers spends
more on than the client spent sending them. Every case holds each
line to the 2,560-byte ceiling. That per-line ceiling
is what the figure above states, and every row establishes it.
Three of the sites go further and bound the whole flood's output — the