Skip to content

fix(security): contain private session artifacts - #1249

Open
sethkarten wants to merge 7 commits into
mainfrom
sethkarten/security-private-files
Open

fix(security): contain private session artifacts#1249
sethkarten wants to merge 7 commits into
mainfrom
sethkarten/security-private-files

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • validate session identifiers and keep all session-derived paths inside the configured session directory
  • write session, auth, snapshot, debug, refinement, export, editor, and harness artifacts with private modes and atomic/no-follow protections
  • reject symlink and non-regular-file sinks where sensitive data could otherwise escape or be exposed

This is the private-storage portion extracted from #1159 and proposed directly against current main.

Risk

Medium. The change intentionally rejects unsafe pre-existing paths and symlinks. Existing regular files remain supported and are repaired to private modes where appropriate. User-selected HTML export directories are not chmodded; the emitted file itself remains private.

Provenance

The two commits preserve cherry picked from trailers for original commits b0ce5adf20ec8c891dd44e8b39bdb0ab453a5eba and 4ede067b97f803957af36aefe16487e15851c363 from #1159. No MCP/provider changes are included.

Validation

  • npm run check
  • npx vitest --run test/suite/regressions/1105-session-storage-security.test.ts test/suite/regressions/1105-named-sinks-security.test.ts test/kernel-state-snapshot.test.ts test/interactive-mode-debug-command.test.ts — 31 passed
  • PYTHONPATH=prime-agent-runtime/src python3 -m unittest prime-agent-runtime/test/test_harness.py — 36 passed
  • focused Biome check on all changed TypeScript files
  • git diff --check origin/main...HEAD

Review focus

Please focus on path containment, symlink/non-regular-file rejection, POSIX mode repair, Windows fallbacks, and the intentionally different parent-directory policy for user-selected HTML exports.


Note

Medium Risk
Touches core persistence and intentionally rejects unsafe existing paths/symlinks; behavior changes on Windows and environments without O_NOFOLLOW, though regular files are repaired where possible.

Overview
This PR hardens session, auth, harness, refinement, snapshot, export, and temp-file paths so sensitive data cannot escape via traversal IDs, symlinks, or permissive modes.

It introduces utils/private-files.ts and replaces scattered fs usage with helpers that enforce 0o700/0o600, atomic writes, and O_NOFOLLOW (no insecure fallback). SessionManager now validates session IDs, confines artifact dirs under session-artifacts, rejects symlink/non-regular transcripts, and uses ownsSessionDir so user-selected transcript parents are not chmodded. Auth, refinement/harness, IPython snapshots, HTML export, and editor/share temps go through the same layer; Windows gets in-memory harness state and /refine fails early. README documents POSIX requirements and residual race limits.

Reviewed by Cursor Bugbot for commit c498fb9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Harden session and artifact storage against symlink attacks, path traversal, and permissive file modes

  • Introduces utils/private-files.ts with O_NOFOLLOW-based helpers (ensurePrivateFile, readPrivateFile, writePrivateFileAtomic, appendPrivateFile, createPrivateTempFile, etc.) that enforce 0o700/0o600 permissions and reject symlinks at every step.
  • Replaces direct fs calls throughout session, auth, harness, refinement, and interactive-mode code paths with these privacy-aware helpers, making all sensitive file reads and writes atomic and symlink-safe.
  • Adds session ID validation (SESSION_ID_PATTERN) to reject traversal IDs, and validates artifact directory paths against path-escape and symlink attacks in SessionManager.
  • Disables persistent harness storage and /refine on Windows, returning in-memory state with a clear error instead of attempting filesystem access.
  • Hardens the Python kernel snapshot/restore helpers in state-snapshot.ts to require O_NOFOLLOW, use atomic temp-file writes with 0o600, and reject symlinked or non-regular destinations.
  • Risk: Systems without O_NOFOLLOW (and Windows for harness persistence) now fail closed rather than falling back to unsafe operations.

Changes since #1249 opened

  • Added conditional parent directory permission enforcement to private file utilities [c498fb9]
  • Integrated ownsSessionDir flag into SessionManager to control directory permission enforcement [c498fb9]
  • Removed exports for SESSION_ID_PATTERN constant and assertValidSessionId function [c498fb9]
  • Added test coverage verifying parent directory permissions are preserved when opening user-selected transcripts [c498fb9]

Macroscope summarized cf9e3ae.

Comment thread packages/coding-agent/src/utils/private-files.ts
Comment thread packages/coding-agent/src/core/session-manager.ts
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread packages/coding-agent/src/modes/interactive/components/extension-editor.ts Outdated
Comment thread prime-agent-runtime/src/rlm/harness.py
Comment thread prime-agent-runtime/src/rlm/harness.py
Comment thread packages/coding-agent/src/utils/private-files.ts
Comment thread packages/coding-agent/src/utils/private-files.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch 2 times, most recently from a43daa3 to d948433 Compare August 11, 2026 18:58
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread packages/coding-agent/src/utils/private-files.ts
Comment thread packages/coding-agent/src/utils/private-files.ts Outdated
Comment thread packages/coding-agent/src/core/refinement/refinement.ts
Comment thread packages/coding-agent/src/utils/private-files.ts Outdated
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from d948433 to 344d4e3 Compare August 11, 2026 19:11
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 344d4e3 to 62618aa Compare August 11, 2026 19:16
Comment thread packages/coding-agent/src/core/refinement/refinement.ts
Comment thread packages/coding-agent/src/utils/private-files.ts
Comment thread prime-agent-runtime/src/rlm/harness.py
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 39b3b0e to 3f63142 Compare August 11, 2026 19:21
Comment thread packages/coding-agent/src/core/agent-session.ts
Comment thread packages/coding-agent/src/core/kernel/state-snapshot.ts Outdated
Comment thread packages/coding-agent/src/core/refinement/refinement.ts
Comment thread packages/coding-agent/src/utils/private-files.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 3f63142 to 6c0e62c Compare August 11, 2026 19:27
Comment thread packages/coding-agent/src/utils/private-files.ts Outdated
Comment thread packages/coding-agent/src/core/refinement/refinement.ts
Comment thread packages/coding-agent/src/core/kernel/state-snapshot.ts
Comment thread packages/coding-agent/src/utils/private-files.ts Outdated
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch 3 times, most recently from 5d6f2b8 to 351dd9a Compare August 11, 2026 19:38
Comment thread packages/coding-agent/src/core/kernel/state-snapshot.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 351dd9a to ac475fd Compare August 11, 2026 19:39
Comment thread packages/coding-agent/src/core/agent-session.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from ac475fd to 697a920 Compare August 11, 2026 19:41
Comment thread packages/coding-agent/src/core/refinement/refinement.ts Outdated
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 697a920 to fc0988a Compare August 11, 2026 19:43
Comment thread packages/coding-agent/src/core/session-manager.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from fc0988a to 0327faf Compare August 11, 2026 19:45
Comment thread packages/coding-agent/src/core/session-manager.ts
Comment thread packages/coding-agent/src/utils/private-files.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 0327faf to 762f947 Compare August 11, 2026 19:49
Comment thread packages/coding-agent/src/core/auth-storage.ts
Comment thread packages/coding-agent/src/utils/private-files.ts Outdated
Comment thread packages/coding-agent/src/config.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch 2 times, most recently from ce6aea4 to 7f86590 Compare August 11, 2026 19:55
Comment thread packages/coding-agent/src/core/session-manager.ts
Comment thread packages/coding-agent/src/core/refinement/refinement.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch 2 times, most recently from b813e92 to ec933cf Compare August 11, 2026 20:08
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch 2 times, most recently from 4040af1 to 7b0751d Compare August 11, 2026 20:15
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread packages/coding-agent/src/core/session-manager.ts
Comment thread packages/coding-agent/src/utils/private-files.ts
Comment thread packages/coding-agent/src/core/kernel/state-snapshot.ts
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from 7b0751d to da27926 Compare August 11, 2026 20:21
@sethkarten
sethkarten force-pushed the sethkarten/security-private-files branch from da27926 to 6006f3d Compare August 11, 2026 20:22
@sethkarten
sethkarten requested a review from Apocrathia August 11, 2026 21:45
@Apocrathia

Copy link
Copy Markdown
Contributor

@codex review

@Apocrathia Apocrathia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do a pass to make sure we're actually using this new utility in the places that actually matter.

Comment thread packages/coding-agent/src/core/agent-session.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6006f3d407

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/coding-agent/src/utils/private-files.ts Outdated
Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread prime-agent-runtime/src/rlm/harness.py Outdated
Comment thread packages/coding-agent/src/core/session-manager.ts
Comment thread packages/coding-agent/src/core/kernel/state-snapshot.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cf9e3ae. Configure here.

Comment thread packages/coding-agent/src/core/session-manager.ts Outdated
Comment thread packages/coding-agent/src/core/session-manager.ts
@sethkarten

Copy link
Copy Markdown
Contributor Author

@Apocrathia Ready for re-review. The private-file utility now covers JSONL export and RLM artifact-directory boundaries, all five automated security findings are fixed with behavioral/race coverage, current main is merged, CI is green, and all review threads are resolved.

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