https://gitlab.synchro.net/main/sbbs/-/commit/814c46c6b12043d4ce293d58
Modified Files:
docs/superpowers/specs/2026-07-31-hashed-password-storage-design.md
Log Message:
docs: weigh the two storage options against each other honestly
This pass is about the comparison the document was failing to make, and
about a claim that made it look like there was nothing to compare.
"Why the digest authentication schemes must go" was stated
unconditionally. It opened by observing that a server verifying an HMAC
keyed by the password must hold something password-equivalent, and that
no storage format changes this. Encryption changes it exactly: it holds
the password and can recover it, which is the reversibility the whole
trade is about. The section therefore read as though the deprecations
followed from moving credentials out of user.tab, when they are the price
of the hashing branch alone. It is now titled and framed as conditional,
and its table column says "fate under hashing".
The two branches were also argued asymmetrically. Encryption's drawbacks appeared as a list where the choice is posed; hashing's -- the digest deprecations, password-by-email, retroactive auditing, client
reconfiguration, the transport regression -- were scattered across four
later sections, so a reader had one column in front of them and had to
assemble the other. A side-by-side ledger now sits at the decision point, covering the three properties, the failure mode, each capability that
dies, client reconfiguration, transport, key management and the portable
floor. Neither column is empty, and the choice is not deducible from it: hashing's costs are certain, immediate and land on identifiable users,
while encryption's is a low-probability event with an unbounded blast
radius.
That weighing is now recorded rather than left implicit, as a judgment
and not a measurement. At-rest exposure is both the more likely and the
more severe threat: it is present on every system since each account was created and in every backup, where interception requires an attacker
positioned on a path, and the realistic adversary for a hobby BBS is
commodity infostealer malware scraping files rather than anyone on the
wire. One interception yields one credential for one session; one copy of user.tab yields every account retroactively, with no detection and no
expiry. The protection being defended is narrower than it looks, besides
-- CRAM-MD5 and APOP cover the mail protocols, while terminal login, FTP
and HTTP Basic send the password in the clear today and are untouched by
them (login.cpp:102, ftpsrvr.cpp:2684, websrvr.cpp:2142).
Two qualifications are recorded as insufficient to reverse it: an
intercepted CRAM-MD5 exchange is an unsalted MD5 HMAC over a known
challenge and so is offline-crackable, and the affected users currently
have both exposures. Two things follow. A sysop confident in their
storage whose users are on hostile networks has a real argument for
encryption. And refusing plaintext authentication on unencrypted
connections is not negotiable, since silently moving CRAM-MD5 users to
PLAIN on port 110 is the worst outcome available and the default if
nobody decides otherwise.
Preceding that, two claims defending the deprecations are withdrawn.
Hashed storage "needs no user action" only where nothing about the login changes -- terminal, FTP, HTTP Basic, and clients already sending plain credentials over TLS -- and not for anyone who must reconfigure a mail
client. And a server-side replacement is not a replacement unless the
client can reach it: a POP3 client with CRAM-MD5 and no TLS sends a
digest today and never transmits the password, but after removal either
stops working or sends it in cleartext. That is a transport-security loss
for a subset in exchange for an at-rest gain for all, and calling the server-side work a "replacement path" hid that it is a trade. SCRAM does
not rescue that population either, since the clients in question do not implement it.
Finally, the key-storage section stopped treating a preinstalled package
as an operating-system capability. It listed systemd-creds as what
"Linux" offers and the BSDs as having "nothing standard", comparing a
package that happens to be preinstalled against one that happens not to
be. Only DPAPI and the macOS Keychain are base-system facilities;
systemd-creds is systemd, which Alpine, Void, Devuan and OpenRC systems
do not have, and TPM2 sealing is hardware plus tpm2-tss, a package or
port everywhere including the BSDs. The axis is default availability, not standardness, and the real capability question is whether the machine has
a TPM -- which cuts across OS families. The table now records where each facility comes from, adds the row that was missing (a mode-0600 file, the floor, which works everywhere), and the design names none of them:
Synchronet reads the key from a location the sysop configures, and how
that location is protected is their platform's business.
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net