fix: require link possession (auth key) to fetch/delete passwordless notes - #40
Merged
Merged
Conversation
- llms-full.txt DELETE: passwordHash is required for password-protected notes (403 otherwise); only optional for unpassworded notes - llms-full.txt .env workflow: consumers must resolve via 'vailnote env' before use; add rotation + expiry guidance - README: never sends 'raw password' (only PBKDF2 hash for access control) - README: mention 'env' command in AI-agent ready bullet
…notes The server never stored a verifier for the auth key, so any caller who knew only the note ID could fetch (destroying auto-delete notes) or delete an unpassworded note - the #auth= fragment was never checked. - Server: accept authKeyHash at create (bcrypt'd deterministic PBKDF2 verifier), require it on fetch and delete for passwordless notes; legacy notes without a verifier keep ID-addressable behavior - CLI: send authKeyHash on create/read/delete; delete now refuses links without #auth= (or a password) before hitting the network - Web client: send authKeyHash on create/fetch/delete via NoteService/RemoteStorage (authKey threaded from the link fragment) - Tests: new CRUD step covering 403 without verifier, 200 with it for both fetch and delete; full suite green (28 passed / 44 steps) - Docs: llms-full.txt create/fetch/delete updated with authKeyHash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
vailnote delete https://vailnote.com/<id>(no#auth=fragment) deleted the note. The server never stored any verifier for the auth key — for passwordless notes, possession of the note ID alone was enough to fetch (which destroys auto-delete notes) or delete.Root cause
Zero-knowledge means the server never sees the auth key. But it also means it can't check it — so the ID (12 hex chars, leaks from logs/proxies/history) became the de-facto capability for passwordless notes. The
#auth=fragment was verified by nothing on the server.The fix (zero-knowledge preserved)
Mirror the existing password-verifier pattern for the auth key:
authKeyHash= deterministic PBKDF2 hash of the auth key → server storesbcrypt(authKeyHash)(one-way; same as the password verifier)authKeyHash→403 INVALID_PASSWORD_OR_AUTH_KEYotherwise; ID alone is never enoughauthKeyHashon create/read/delete;vailnote deletenow refuses a link without#auth=(or a password) locallyNoteService/RemoteStoragethread the auth key from the link fragment and send the verifier on create/fetch/deleteSecurity notes
Verification
authKeyHash→ fetch/delete without verifier = 403, with verifier = 200 (manual-deletion note so fetch doesn't destroy it)deno check main.ts cli/main.tsclean