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
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
- Project: `/home/avi/Projects/0_Nostr`
- Git repo: `master` @ `4bd7660` ("Tighten permissions on leftover legacy vault files").
Before it: `4d4dfde` (CSP + navigation guards), `6e627a3` (upload pick tokens),
`4bde395` (IPC allowlist), on top of contact-aware feed (`a1445d1`) etc.
- Git repo: `master` @ `4461307` ("Create vault files owner-only from the first byte").
Before it: `4bd7660` (legacy vault perms), `4d4dfde` (CSP + navigation guards),
`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.
## What was completed: security hardening items #1#4
## What was completed: security hardening items #1#5
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 /
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
- `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).
- `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,
@ -112,11 +124,10 @@ Manual protocol checks worth doing once:
Remaining audit items in priority order:
1. **Write-race fixes** — create files with mode 0600 at creation time in `vault.rs`
(`write_restricted`, `backup_file` currently chmod after creating).
2. **Zeroize** — wipe decrypted key material via the `zeroize` crate.
3. Smaller: link-preview SSRF guard (block loopback/private IPs), signer pending-cap,
1. **Zeroize** — wipe decrypted key material via the `zeroize` crate (`VaultKey`,
decrypted hex strings in `crypto.rs`/`profiles.rs`).
2. Smaller: link-preview SSRF guard (block loopback/private IPs), signer pending-cap,
NIP-46 secret echo check, backend request timeout.
All four high/medium user-facing findings from the audit are now closed (#1 IPC allowlist,
#2 upload tokens, #3 CSP + navigation, #4 legacy vault perms).
All five medium findings from the audit are closed (#1 IPC allowlist, #2 upload tokens,
#3 CSP + navigation, #4 legacy vault perms, #5 write-race windows).