Skip to content

fix(store): don't silently create a second store; restrict store perms to 0700 - #24

Merged
vicentereig merged 1 commit into
vicentereig:mainfrom
mikrub:fix/store-creation-and-permissions
Jul 27, 2026
Merged

vicentereig merged 1 commit into
vicentereig:mainfrom
mikrub:fix/store-creation-and-permissions

Conversation

@mikrub

@mikrub mikrub commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Two related problems with how the store directory is created.

1. Silent duplicate stores

--store defaults to a CWD-relative ./store, and the store/client constructors create it unconditionally. So running any command from the wrong directory creates an empty second store instead of reporting the mistake. Every later command run from there reads that empty store and reports zero messages — indistinguishable from data loss. An auth against such a directory is worse: it leaves real session keys somewhere nobody is tracking.

This is not hypothetical. It happened three times in a single working session after I had identified the behaviour and was actively watching for it — twice from running the binary directly instead of through a wrapper, once from a go test run inside the repo. That is why I do not think documentation fixes it.

Only auth may now bring a store into existence; every other command errors with the resolved path:

$ whatsapp-cli chats list
{"success":false,"data":null,"error":"store does not exist: /wrong/dir/store (run 'auth' to create it, or pass --store)"}

2. Permissions

The store directories were created 0755, and SQLite creates the DBs 0644 under the usual umask. whatsapp.db holds the linked-device session keys — read access is account impersonation — and messages.db holds the plaintext message archive with contact names and phone numbers. Both are now 0700, along with the media output directory. Media files themselves were already 0600 via CreateTemp+Rename; the directory was the only part left readable.

Tests

checkStorePresence is extracted as a pure function and table-tested, including that it does not create the directory as a side effect. Store permissions are asserted in internal/store.

go build ./..., go test ./... and go test -race ./... all pass.

…s to 0700

Two related problems with how the store directory is created.

1. --store defaults to a CWD-relative "./store" and the constructors create it
   unconditionally, so running any command from the wrong directory silently
   creates an empty store instead of reporting the mistake. Every later command
   run from there reads that empty store and reports zero messages, which is
   indistinguishable from data loss; an 'auth' against it leaves real session
   keys in a directory nobody is tracking. Only 'auth' may now bring a store
   into existence — everything else errors with the resolved path.

2. The store directories were created 0755, and SQLite creates the DBs 0644
   under the usual umask. whatsapp.db holds the linked-device session keys
   (read access = account impersonation) and messages.db holds the plaintext
   message archive. Both are now 0700, along with the media output directory —
   media files themselves were already 0600.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vicentereig
vicentereig merged commit 4517021 into vicentereig:main Jul 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants