audit 4: sign-in timing and sessions, server timeouts, polling that recovers
test / test (push) Canceled after 0s

Steps 1-3 of stage 4, tested together (their docs share files).

Step 1 (M8, L15, L16): an unknown name pays a bcrypt comparison at the
panel's work factor too (noSuchUserHash, made once) -
TestLoginTakesAsLongForAnUnknownName holds the medians within a factor of
two; the Account form's current-password check has its own limiter, per
user (AllowPasswordChange); a sign-in destroys every session the request
presents before it issues its own.

Step 2 (L14): newHTTPServer - ReadTimeout 30 s, WriteTimeout 60 s,
IdleTimeout 2 min beside ReadHeaderTimeout; the full backup moves its write
deadline to two hours through http.ResponseController (e2e: the log shows
no failure to move it).

Step 3 (M11), read in htmx 2.0.4's source (dev/upstream/htmx-2.0.4, the npm
build byte-equal to the shipped htmx.min.js): the poll passes source: box,
and the next refresh is scheduled from htmx:afterRequest, which htmx fires
on load, error, abort and timeout, and after a swap on the nearest parent
left (the box found by detail.target's id); failures in a row double the
wait to 60 s. RequireAuth answers htmx with 401 + HX-Redirect: /login,
which htmx follows before it looks at the status. testdata/poll_test.js
runs panel.js in node against a stand-in DOM and clock (TestPanelJS; skipped
without node, which the test server lacks - run here, and it fails on the
old panel.js).

Also measured: the stage-3 e2e regression for H1 fails as it should on HEAD
with the old entrypoint ("check data/postfix/e2e_extra_map: permission
denied", the panel restarting).

Tested on the test server: go vet + go test of 25 packages, make e2e (all
pass, 639 s) on this tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-15 11:07:02 +03:00
co-authored by Claude Opus 5.5
parent 48832d223a
commit 07be0cfb58
18 changed files with 535 additions and 43 deletions
+27
View File
@@ -5,6 +5,33 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
## [Unreleased]
### Security
- **The sign-in told which usernames exist by how long it took.** A wrong
password cost a bcrypt comparison, an unknown name none. Both now cost one
(audit 2026-10-12, M8).
- **Signing in kept the session the browser already presented.** A sign-in
now ends it before it issues its own, so a session planted before the
sign-in is worth nothing after (audit 2026-10-12, L16).
### Fixed
- **Ten wrong current passwords on Account locked the address out of
signing in for 15 minutes.** The check has its own limit now, ten in 15
minutes per user (audit 2026-10-12, L15).
- **A client could hold the panel's server as long as it liked** once its
request header was read. The body now has 30 seconds, the answer 60, an
idle kept-alive connection 2 minutes; a full backup download moves its own
limit to two hours (audit 2026-10-12, L14).
- **One failed refresh stopped a monitoring page for good.** Overview,
Health and the logs refresh their boxes on a timer; a refresh that failed
- the panel restarting, the network gone - scheduled no next one, and the
page stood still until the tab was hidden and shown again. Each refresh
now schedules the next however it ended, waiting twice as long after each
failure in a row, up to a minute. A box whose session had expired was
filled with the sign-in page; the whole page goes to sign-in now (audit
2026-10-12, M11).
## [2.5.3] - 2026-10-15
Stage 3 of the 2026-10-12 audit: persistence and restore. A restore is