Refresh checkpoint with legacy vault hardening

This commit is contained in:
Avi 2026-08-21 14:59:28 -05:00
commit 848e29589c

View file

@ -1,4 +1,4 @@
# Checkpoint — Header-based CSP + navigation guards (2026-08-21) # Checkpoint — Legacy vault permission hardening (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,12 @@ 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` @ `4d4dfde` ("Enforce header-based CSP and block window open/navigation"). - Git repo: `master` @ `4bd7660` ("Tighten permissions on leftover legacy vault files").
Before it: `6e627a3` (upload pick tokens), `4bde395` (IPC allowlist), then checkpoint Before it: `4d4dfde` (CSP + navigation guards), `6e627a3` (upload pick tokens),
commits, on top of contact-aware feed (`a1445d1`) etc. `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, #2 and #3 ## What was completed: security hardening items #1#4
Fixes from the 2026-08-21 security audit. Fixes from the 2026-08-21 security audit.
@ -55,8 +55,23 @@ page could read+publish arbitrary local files to nostr.build. Now:
- `setWindowOpenHandler`: all `target="_blank"` popups are denied; external links go to the - `setWindowOpenHandler`: all `target="_blank"` popups are denied; external links go to the
system browser. Unknown schemes are denied without opening anything. system browser. Unknown schemes are denied without opening anything.
**#4 Legacy vault permissions (`4bd7660`):**
- The original CLI left `profiles_vault.json` files with default (often group-readable)
permissions containing plaintext keys. Now:
- On **every** startup, `load_vault()` calls the new `harden_stray_legacy_vaults()`
(`src/vault.rs`): each known legacy location is checked, and any file that parses as a
populated vault is chmod'd to 0600 — whether or not migration ever runs.
- During migration itself, the legacy file is tightened before the backup copy is made.
- Hardening is best-effort (`let _ =`) so odd filesystems can never break vault loading;
unparsable and keyless files are deliberately not touched.
- One-time local cleanup done by hand in this session: repo-root `profiles_vault.json`
was chmod'd from 0664 → 0600.
- New tests: recognised legacy vault tightened to 0600; unparsable file ignored; empty /
encrypted-but-populated vaults classified correctly.
## Commits ## Commits
- `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,
types.ts, AppProvider.tsx, ComposeScreen.tsx, fakeBackend.ts (+62/27). types.ts, AppProvider.tsx, ComposeScreen.tsx, fakeBackend.ts (+62/27).
@ -97,10 +112,11 @@ Manual protocol checks worth doing once:
Remaining audit items in priority order: Remaining audit items in priority order:
1. **Legacy vault perms** — repo-root `profiles_vault.json` is group-readable (0664); 1. **Write-race fixes** — create files with mode 0600 at creation time in `vault.rs`
chmod 600 / delete after confirming migration; auto-tighten during migration in `src/vault.rs`. (`write_restricted`, `backup_file` currently chmod after creating).
2. **Write-race fixes** — create files with mode 0600 at creation time in `vault.rs` 2. **Zeroize** — wipe decrypted key material via the `zeroize` crate.
(`write_restricted`, `backup_file`). 3. Smaller: link-preview SSRF guard (block loopback/private IPs), signer pending-cap,
3. **Zeroize** — wipe decrypted key material via the `zeroize` crate.
4. 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,
#2 upload tokens, #3 CSP + navigation, #4 legacy vault perms).