v1.27.17
[1.27.17] — 2026-08-16
Release notes
Security fixes
- Per-backup random keys (was: deterministic nonce). A v1 backup derived
its AES-GCM nonce fromSHA-256(passphrase || created_at)— two backups
within the same second reused the identical nonce (catastrophic in GCM).
Backups now use argon2id key derivation with a random 16-byte salt and a
random 12-byte nonce sourced per backup from the RNG (new format; legacy
v1 files still restore). - Argon2id key derivation (was: SHA-256). v1 derived the 32-byte key with
a single SHA-256 of the passphrase — offline dictionary attacks at trivial
cost. New backups use argon2id (64 MiB / 3 passes / 1 lane, tuned to stay
under ~2 s on dev hardware). - Plaintext snapshot is 0600 at birth (was: umask-dependent). The
safety-snapshot / backupVACUUM INTOfile was created with umask-derived
permissions and chmod'd only after success — a crash inside the window left
readable plaintext. Snapshot files are now created 0600 viacreate_new
(a pre-existing file at the path aborts, never overwrites) and are removed
on every failure path. - Restore refuses to clobber the previous safety snapshot. Restoring over
an existing target already preserved the pre-restore state as<db>.bak;
a second restore silently failed on that file with a cryptic SQL error. It
now fails-closed with a clear message before touching the disk.
Improvements
brain backupgains--format v1|v2(default v2); restore and
brain doctor --backupauto-detect both formats.- Backup refuses to run while a stale
brain.bakexists (a swapped/truncated
source DB was previously enshrined as the "safety snapshot").
Full Changelog: v1.27.16...v1.27.17