Refresh checkpoint with owner-only file writes

This commit is contained in:
Avi 2026-08-21 15:18:43 -05:00
commit 467d2697af

View file

@ -1,4 +1,4 @@
# Checkpoint — Legacy vault permission hardening (2026-08-21) # Checkpoint — Owner-only-from-first-byte file writes (2026-08-21)
A stopping point you can return to if this session is closed. Everything below was A stopping point you can return to if this session is closed. Everything below was
verified green at the moment this file was written. verified green at the moment this file was written.
@ -6,12 +6,13 @@ verified green at the moment this file was written.
## Where things are ## Where things are
- Project: `/home/avi/Projects/0_Nostr` - Project: `/home/avi/Projects/0_Nostr`
- Git repo: `master` @ `4bd7660` ("Tighten permissions on leftover legacy vault files"). - Git repo: `master` @ `4461307` ("Create vault files owner-only from the first byte").
Before it: `4d4dfde` (CSP + navigation guards), `6e627a3` (upload pick tokens), Before it: `4bd7660` (legacy vault perms), `4d4dfde` (CSP + navigation guards),
`4bde395` (IPC allowlist), on top of contact-aware feed (`a1445d1`) etc. `6e627a3` (upload pick tokens), `4bde395` (IPC allowlist), on top of contact-aware
feed (`a1445d1`) etc.
- Working tree is **clean** apart from this checkpoint update, which is committed right after. - Working tree is **clean** apart from this checkpoint update, which is committed right after.
## What was completed: security hardening items #1#4 ## What was completed: security hardening items #1#5
Fixes from the 2026-08-21 security audit. Fixes from the 2026-08-21 security audit.
@ -69,8 +70,19 @@ page could read+publish arbitrary local files to nostr.build. Now:
- New tests: recognised legacy vault tightened to 0600; unparsable file ignored; empty / - New tests: recognised legacy vault tightened to 0600; unparsable file ignored; empty /
encrypted-but-populated vaults classified correctly. encrypted-but-populated vaults classified correctly.
**#5 Owner-only-from-first-byte writes (`4461307`):**
- `write_restricted` (`src/vault.rs`): the tmp file is now created with `.mode(0o600)`
(OpenOptionsExt), so it never exists under default umask permissions. The explicit
`set_permissions` stays, covering a tmp file left over by a crashed earlier run (where
`mode` would not apply to an existing file).
- `backup_file`: replaced `fs::copy` — which gives the new file the *source's* permission
bits, so backing up a group-readable legacy vault briefly produced a fully readable copy —
with a manual open-at-0600 + `io::copy`, making backups owner-only from their first byte.
- New test: backup of a 0664 source comes out 0600 with identical content.
## Commits ## Commits
- `4461307` "Create vault files owner-only from the first byte" — src/vault.rs (+48/2).
- `4bd7660` "Tighten permissions on leftover legacy vault files" — src/vault.rs (+79/3). - `4bd7660` "Tighten permissions on leftover legacy vault files" — src/vault.rs (+79/3).
- `4d4dfde` "Enforce header-based CSP and block window open/navigation" — main.ts + index.html. - `4d4dfde` "Enforce header-based CSP and block window open/navigation" — main.ts + index.html.
- `6e627a3` "Replace upload file paths with single-use pick tokens" — main.ts, api.ts, - `6e627a3` "Replace upload file paths with single-use pick tokens" — main.ts, api.ts,
@ -112,11 +124,10 @@ Manual protocol checks worth doing once:
Remaining audit items in priority order: Remaining audit items in priority order:
1. **Write-race fixes** — create files with mode 0600 at creation time in `vault.rs` 1. **Zeroize** — wipe decrypted key material via the `zeroize` crate (`VaultKey`,
(`write_restricted`, `backup_file` currently chmod after creating). decrypted hex strings in `crypto.rs`/`profiles.rs`).
2. **Zeroize** — wipe decrypted key material via the `zeroize` crate. 2. Smaller: link-preview SSRF guard (block loopback/private IPs), signer pending-cap,
3. Smaller: link-preview SSRF guard (block loopback/private IPs), signer pending-cap,
NIP-46 secret echo check, backend request timeout. NIP-46 secret echo check, backend request timeout.
All four high/medium user-facing findings from the audit are now closed (#1 IPC allowlist, All five medium findings from the audit are closed (#1 IPC allowlist, #2 upload tokens,
#2 upload tokens, #3 CSP + navigation, #4 legacy vault perms). #3 CSP + navigation, #4 legacy vault perms, #5 write-race windows).