Skip to content

fix(browser): write network cache file with 0o600 owner-only permissions#1766

Open
Benjamin-eecs wants to merge 1 commit into
jackwener:mainfrom
Benjamin-eecs:fix/network-cache-file-permissions
Open

fix(browser): write network cache file with 0o600 owner-only permissions#1766
Benjamin-eecs wants to merge 1 commit into
jackwener:mainfrom
Benjamin-eecs:fix/network-cache-file-permissions

Conversation

@Benjamin-eecs
Copy link
Copy Markdown
Contributor

Description

saveNetworkCache in src/browser/network-cache.ts writes the browser network cache via fs.writeFileSync(target, JSON.stringify(payload), 'utf-8') with no mode option. The kernel applies the process umask, so the file lands as 0644 and is readable by any local user. The file at ~/.opencli/cache/browser-network/<session>.json stores up to a day of entries[].body payloads from every browser-backed adapter call, which routinely include auth tokens, session cookies, and PII. This is the same class of leak that #1742 fixed in exportCookiesToNetscape; apply the same fs.openSync + fs.fchmodSync pattern so new files are owner-only and pre-existing broad-permission files are tightened on rewrite.

Related issue: fixes #1765 (this is the same defense-in-depth thread continued from #1742; the larger Finding 5 in #847 about capture-by-default behavior is separate and not addressed here).

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌐 New site adapter
  • 📝 Documentation
  • ♻️ Refactor
  • 🔧 CI / build / tooling

Checklist

  • I ran the checks relevant to this PR
  • I updated tests or docs if needed
  • I included output or screenshots when useful

Screenshots / Output

Two tests added next to existing siblings in src/browser/network-cache.test.ts, mirroring the #1742 layout:

  • writes the cache file with 0o600 owner-only permissions covers the new-file case
  • tightens an existing cache file before rewriting it pre-creates a 0o644 file and asserts the rewrite drops it to 0o600 while preserving round-trip via loadNetworkCache

Both skipped on Windows via it.skipIf(process.platform === 'win32') since POSIX mode bits do not apply there. Full suite: 511/511 pass on this branch.

@Benjamin-eecs Benjamin-eecs changed the title fix(browser): write network cache file with 0o600 owner-only permissions (fixes #1765) fix(browser): write network cache file with 0o600 owner-only permissions May 27, 2026
@Benjamin-eecs Benjamin-eecs force-pushed the fix/network-cache-file-permissions branch from 951c4c2 to 1428dec Compare May 27, 2026 06:07
@Benjamin-eecs Benjamin-eecs marked this pull request as ready for review May 27, 2026 06:09
Copilot AI review requested due to automatic review settings May 27, 2026 06:09
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR hardens the on-disk browser network cache to reduce the risk of leaking sensitive captured response data (auth tokens / PII) by ensuring cache files are written with owner-only permissions.

Changes:

  • Write the cache file via an explicit file descriptor and apply 0o600 permissions before writing.
  • Add non-Windows tests asserting the cache file is created/tightened to 0o600.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/browser/network-cache.ts Writes cache files with owner-only permissions using openSync + fchmodSync + writeFileSync(fd, ...).
src/browser/network-cache.test.ts Adds POSIX-only tests for 0o600 permissions and tightening an existing file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +68 to +72
let fd: number | undefined;
try {
fd = fs.openSync(target, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_TRUNC, 0o600);
fs.fchmodSync(fd, 0o600);
fs.writeFileSync(fd, JSON.stringify(payload), 'utf8');
Comment on lines +70 to +72
fd = fs.openSync(target, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_TRUNC, 0o600);
fs.fchmodSync(fd, 0o600);
fs.writeFileSync(fd, JSON.stringify(payload), 'utf8');
// bodies. fchmod before writing also tightens a pre-existing broad file.
let fd: number | undefined;
try {
fd = fs.openSync(target, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_TRUNC, 0o600);
Captured response bodies can leak auth tokens; apply the openSync + fchmod pattern from jackwener#1742.

Fixes jackwener#1765
@Benjamin-eecs Benjamin-eecs force-pushed the fix/network-cache-file-permissions branch from 1428dec to 0ffd9b0 Compare May 27, 2026 13:41
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.

[Bug]: browser network cache file written with world-readable 0644 permissions can leak captured response bodies

2 participants