Skip to content

Protect app-created session history from other local accounts #445

Closed

Description

@Broccolito

Audit observation

On the official BioRouter v1.93.4 Linux CLI release, a separate non-root account could read a synthetic session title from the SQLite session store in three fresh fixtures when the home path was traversable and the app-created session directory had mode 0755. The observer did not use the daemon credential or run as the owning UID. No PHI or real credentials were used.

This is a local confidentiality issue under shared-host permissions. It does not demonstrate a remote compromise or same-user isolation.

Current status

A source change on the local codex/security-reviewer-assessment branch opens the session directory without following a final symlink, checks that it is owned by the current account, and restricts it to mode 0700 before opening the database. A regression test covers an existing permissive directory. The change is not merged or released; a separate-account retest against a rebuilt binary remains pending.

Recommendation

Keep the normal startup and research workflow unchanged by automatically enforcing owner-only permissions on app-owned session storage, including existing stores and SQLite sidecars. Apply the equivalent current-user ACL on Windows. If intentional sharing is a supported use case, provide an explicit, narrowly scoped sharing mechanism rather than leaving the database world-readable by default.

Activity

  1. Broccolito commented on Oct 23, 2026

    @Broccolito
    CollaboratorAuthor

    Defensive audit remediation update (local source branch; not released)

    The assessment branch now protects the current-user-owned Unix session directory with O_NOFOLLOW | O_DIRECTORY and mode 0700 before opening SQLite. This includes existing permissive app-owned directories.

    Verified against the frozen assessment source:

    • macOS/arm64 application regressions passed for new and existing storage: owner session creation, reading, closing and reopening remain functional; a final symlink is refused without modifying its target.
    • The exact production guard was compiled separately on Linux/arm64 and checked in three fresh two-UID fixtures. UID 10002 could read the permissive synthetic file before protection, was denied afterward, and owner UID 10001 retained access. Foreign-owned and symlinked directories were also refused.
    • This helper replay is not a rebuilt Linux BioRouter/SQLite end-to-end retest. The original release finding remains the three Linux/amd64 released-app SQLite disclosures already recorded.

    Recommendations preserving normal use: retain automatic repair for app-owned stores without extra prompts; add a recoverable, actionable startup error and safe relocation support. The current constructor rejects symlink-relocated stores through its existing panic-based error path, which is a compatibility limit. Keep permissions scoped to app-owned storage. Windows ACL parity and rebuilt-release verification remain follow-ups; previously opened outsider file descriptors are not revoked.

    Status: source changes and focused regressions are complete locally on codex/security-reviewer-assessment (base f73ebf74c578717a7af64b221e57358a63dda8e3). No merge or fixed distribution is claimed. Leaving this issue open for maintainer review and integration.

  2. Broccolito commented on Oct 24, 2026

    @Broccolito
    CollaboratorAuthor

    Issue #445: Protect session history from other local accounts

    Issue · Host PR #454 · merged main source

    Historical desktop/browser/CLI observations used f227 artifacts, accepted via the reviewed production-equivalence comparison; exact-main CI/build/smoke is attributed separately below.

    Problem. App-created SQLite session history and sidecars could retain permissions readable by another local non-root account.

    Fix and UX. Session preparation establishes owner-private directory/DB/WAL/SHM permissions and checks opened object ownership, type and unsafe aliases before use/repair. Unix extended ACLs are explicitly cleared; Windows protection validates the owned tree before DACL repair. Ordinary history/restart remains automatic. Unsuitable storage returns recovery and real owner-controlled relocation guidance rather than a constructor panic or silent linked-store traversal.

    Validation. The exact merged-main rebuilt Linux job passed 39/39 case records =13 cases × 3 fresh repetitions,234 nested assertions, owner UID 10001 / observer UID 10002. Twelve separate-account expected-denial records span session and undo storage; owner/history/restart and deliberately readable positive controls are retained. Current Windows CI passed session-permission/owner-private units and the private-history bounded-file control. Two separately recorded local macOS ACL targets passed owner-account everyone-ACE repair; macOS CI is related, but did not run those session integration targets.

    Limits. Dedicated Windows session-storage integration and Windows GUI/foreign-UID execution are not claimed; macOS ACL inspection is not a second-UID runtime test. Same-account hostile code, administrators/root/SYSTEM, already-open foreign handles, uncontrolled ancestors and arbitrary network filesystems remain outside the demonstrated boundary. This is not a custom race-proof SQLite VFS.

    Recommendation. Preserve automatic private-store repair for safe owned storage and actionable real-folder relocation for unsuitable storage; do not recover by broadening permissions.

    Merged-main verification. PR454 is merged at 0580110; main Rust CI, frontend CI and related checks finished 20 successes/one skipped (17 push successes plus three landing/deployment checks; these are not security-test counts). Normal main build manifest SHA256: 38cc2979c7da104cb623975bac7f6922a085e834a1be5c18e961d7f26ea811fc; shipping receipt: e6e1d8957d8d0b22a9aae814011a1e028c5d279848ffabbf4c6d0c4edf3c0112. Actual main01 smoke separately recorded four pairs—three reads/one typed Deny—and three unchanged canaries; it does not rerun/recount the historical 81-pair cohort.

    Submission record. Manuscript v1.1 local Supplementary Data S1: Supplementary Data S1 - BioRouter Security Audit - 2026-10-24.zip; manifest SHA256 4f0c0c110ca0b07a29d5281870227f7b36c744a0f37ccb499b8ef1283dea116e. This is a user/submission package, not a claim of public upload. Public PR/source/CI links above provide the public implementation proof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions