Skip to content

fix(local): stop the database being readable by other accounts on the machine - #1594

Open
GeiserX wants to merge 1 commit into
UsefulSoftwareCo:mainfrom
GeiserX:fix/db-file-permissions
Open

fix(local): stop the database being readable by other accounts on the machine#1594
GeiserX wants to merge 1 commit into
UsefulSoftwareCo:mainfrom
GeiserX:fix/db-file-permissions

Conversation

@GeiserX

@GeiserX GeiserX commented Aug 15, 2026

Copy link
Copy Markdown

On a default macOS or Linux install, the local database is readable by every other account on the machine. The two secret files sitting next to it are not.

-rw-r--r--  data.db
-rw-r--r--  data.db-shm
-rw-r--r--  data.db-wal
-rw-------  server-control/auth.json

That is from a real ~/.executor, not a constructed case. auth.json and server-connections.json get a deliberate chmod after write; the database never got one, because SQLite creates its own files with the process umask.

The database is not the less sensitive of the two. It holds:

  • oauth_session.pkce_verifier — a readable live verifier defeats PKCE
  • connection.last_health — response samples taken from the upstream
  • artifact.preview — a rendered artifact with its data
  • for stdio MCP integrations created before the auth-method revamp, plaintext secret env in integration.config

WAL is on, so the -wal sidecar carries recently written rows too.

The fix

chmod the database and its sidecars to 0600 in openLocalLibsql, which every on-disk open path already routes through.

On open rather than on create, so a database written by an earlier version gets tightened too — same reasoning as the mode + chmod pair already in writeToken, since mode only applies at creation. Best-effort per file, so a filesystem without POSIX modes cannot stop the server booting over a permission it cannot set.

How I tested it

Not just that the suite is green — I checked the tests can go red.

  • bun run test in apps/local: 75 passed, 14 files.
  • The new tests drive the real openLocalLibsql against a real file and assert on statSync, because the property is what the filesystem ends up holding.
  • One of them is a positive control that asserts a raw libSQL open does leave the file world-readable. Without it, a chmod that silently stopped running would still look green on a machine with a strict umask.
  • Mutation check: I neutered the chmod call (keeping it compiling) and re-ran. Exactly the two tests that assert the fix went red; the control and the in-memory test correctly stayed green.
  • oxlint on both changed files: 0 warnings, 0 errors. tsgo --noEmit: clean.

The upgrade case has its own test — it seeds a 0644 database first, then opens it, because that is the state every existing install is in today.

… machine

auth.json and server-connections.json are written 0600. The database beside
them is created by SQLite with the process umask, so on a default macOS or
Linux install it lands at 0644, along with its -wal and -shm sidecars.

It is not the less sensitive of the two. It holds live PKCE verifiers,
health-check response samples, artifact previews, and — for stdio MCP
integrations created before the auth-method revamp — plaintext secret env.

chmod on open rather than on create, so a database written by an earlier
version is tightened too. Best-effort per file: a filesystem without POSIX
modes must not stop the server booting over a permission it cannot set.
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.

1 participant