findings of the security review of stage 0
The review of 2c27275..2c8e981 (read-only, a separate agent) found no high or medium; three small ones, fixed here: - reauth took a limiter attempt before the compare, right password included: with A2 asking on every user save, ten saves in fifteen minutes locked the administrator out of Account's password change, the backup and the export. A right password now gives its attempt back (rateLimiter.Refund, Module.PasswordCheckPassed; a bucket already at its limit stays blocked). TestRightAccountPasswordsDoNotUseUpTheLimit. - LoggedPath hid the tokens of /login/reset/ and /confirm/ but not of the first administrator's /setup/<token>; now it does (test case added). - The entrypoint's own `[ -e ] || : >` lines (sender_login_maps, the four inbound maps, mail.log) get the `[ -L ]` guard postfix-config.sh got for I2. Safe before too - drop_links runs first on those paths and the panel is not running yet - this is the belt and braces. The review also confirmed, with a probe of the regex against Postfix's formats, that a port-25 client can place only its own envelope in an Inbound log row, and that every path to a password, e-mail or role asks for the signed-in password. go test ./internal/web/handlers ./internal/web/auth; sh -n entrypoint.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -353,6 +353,7 @@ func (h *Handlers) reauth(r *http.Request, what string) (int, string) {
|
||||
logf("panel: %s: user %d gave a wrong account password", what, p.ID)
|
||||
return http.StatusUnauthorized, "Your account password is incorrect."
|
||||
}
|
||||
h.auth.PasswordCheckPassed(p.ID)
|
||||
return 0, ""
|
||||
}
|
||||
|
||||
|
||||
@@ -134,3 +134,18 @@ func TestUserFormAsksForTheAccountPassword(t *testing.T) {
|
||||
t.Fatalf("delete with the right password = %d:\n%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Only wrong guesses count against the account-password limit: a dozen
|
||||
// right ones in a row - an administrator adding users - leave the next
|
||||
// backup open (review of audit 2026-10-17 stage 0).
|
||||
func TestRightAccountPasswordsDoNotUseUpTheLimit(t *testing.T) {
|
||||
h, st := inboundHandlers(t)
|
||||
root := userWith(t, st, "root", store.RoleGlobal, store.Reach{})
|
||||
withAccountPassword(t, h, st, root)
|
||||
for i := 0; i < 12; i++ {
|
||||
form := url.Values{"username": {"new-user-" + idStr(int64(i))}, "password": {"a-long-enough-password-1"}, "role": {"global"}, "account_password": {testAccountPassword}}
|
||||
if rec := send(h.HandleUserNew, &root, "POST", "/server/users/new", nil, form); rec.Code != http.StatusSeeOther {
|
||||
t.Fatalf("user %d = %d:\n%.600s", i, rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user