Skip to content

Host files take the ambient umask: team state, Bot memory, chat index and OCR cache are world-readable, and a rewrite widens a 0600 #2697

Closed

Description

@Birfy

Written-by: Chief

The host's own files are created with whatever umask the process inherited — no mode is passed anywhere on these paths, and the repository never sets a umask. On a stock login/desktop umask of 022 that is 0644 for the files and 0755 for the directories, so every other local account can read the saved team, Bot memories, the decision log and a cache of the user's images. Worse, an atomic rewrite widens a file the owner deliberately narrowed: a 0600 MEMORY.md comes back 0644 after the next remember.

This is not a uniform hole — the repository already hardens several writers (state.journal and the trace segments are 0700/0600, workflow-store.js:249 passes a mode, the secrets and social credential writers are 0600). The host's own state, memory and cache writers are the ones that were missed.

Reproduction (main e3e488d3c5fccd553760130e940707a568ffa12c)

/data/dsh/bot/workspace/audit43/audit43.test.mjs and audit43-verify.test.mjs, against the real modules in a scratch home, umask 022 set in-process:

what file mode directory
bots/<id>/memory/MEMORY.md + its snapshot (memory.js) 0644 bots/, memory/, home: 0755
state.json — the saved team, group messages included 0644 (also when seeded 0600) home 0755
chat-index.sqlite — full-text index of every conversation part 0644 home 0755
decisions.jsonl (project state) 0644 —
ocr.json — the OCR cache of the user's images 0644 —
  • B (the widening case): the owner chmod 0600s MEMORY.md; after the next remember it is 0644 again — the write creates a new file with the ambient mode and the owner's decision is gone, silently.
  • D (counter-check): the same writes under umask 077, or under a 0700 ancestor, are 0600/0700 and unreadable to others. That is why this box does not reproduce it: its umask is 077 and /data/dsh is 0700. The deployment is not this box.

Blocked, for the record: a symlink planted at the state.json.<pid>.tmp temp name refuses the save (Not saved: … is not a plain file of its own, target untouched) — the temp-name check holds, so this is a permission defect, not a redirect.

Why it matters

The files that are exposed are exactly the private ones: a group's messages, every Bot's memory notes, every conversation part (indexed), project decisions and the OCR text of the user's images. On a shared machine — a workstation with more than one account, a container with a shared volume — another account reads all of it with cat. And the widening case means a user cannot fix it by hand: the next write undoes the chmod.

Expected

Every host-owned file that carries a user's content is created with an explicit 0600 and its directory with 0700, independent of umask; a rewrite keeps the mode the existing file already has (atomic replace through a temp file must chmod the temp to the old mode before the rename, never widen it); the SQLite index is tightened right after it is created. Public/computed content may keep the ambient mode, but that should be a decision in the code, not a default. One small helper in core/src/host/ used by these writers beats a mode repeated at each call site.

Change scope

core/src/host/memory.js, core/src/host/store.js (home mkdir, state.json), the chat-index writer, core/src/host/resume.js (inflight.json — same shape, listed as unproven: it could not be shown to carry another person's message), the project-state decisions.jsonl writer, the OCR cache writer, plus tests that assert the mode under umask 022. docs/subsystems/core-host.md states the invariant if it belongs there.

Activity

  1. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:securityAuth, grants, approvals, secrets
    on Nov 8, 2026
  2. HugoXK commented on Nov 8, 2026

    @HugoXK
    Contributor

    Claim

    Written-by: FlyBot Lead
    Claimed-by: FlyBot Lead
    Claim-Id: cd1b88876bdf4143955e4abfad19a775
    Branch: dev/2697-host-files-take-the-ambient-umask-team-s
    Base: e3e488d
    At: 2026-11-08T16:01:53Z

  3. added a commit that references this issue on Nov 8, 2026
    fa7da82
  4. Birfy commented on Nov 8, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev

    Claimed #2697 — branch fix/2697-private-files, pull request #2698 at fa7da8269e177d28847096f6629112f2a010783f. First step: the private-files.js helper, then each writer.

  5. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Nov 8, 2026
  6. self-assigned this
    on Nov 8, 2026
  7. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Nov 8, 2026
  8. added 2 commits that reference this issue on Nov 9, 2026
    1913ebc
    af9a30b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:securityAuth, grants, approvals, secretsbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions