Summary
The Browse server uses fixed, predictable paths in /tmp for log files and creates them with default (world-readable) permissions, leaking browsing activity to any local user.
Affected Code
browse/src/server.ts:37-38 — Predictable log paths:
const CONSOLE_LOG_PATH = `/tmp/browse-console${INSTANCE_SUFFIX}.log`;
const NETWORK_LOG_PATH = `/tmp/browse-network${INSTANCE_SUFFIX}.log`;
browse/src/server.ts:52,63 — Log files written with default permissions:
fs.appendFileSync(CONSOLE_LOG_PATH, lines);
fs.appendFileSync(NETWORK_LOG_PATH, lines);
browse/src/server.ts:202-203 — Old logs deleted with unlink (symlink race window):
try { fs.unlinkSync(CONSOLE_LOG_PATH); } catch {}
try { fs.unlinkSync(NETWORK_LOG_PATH); } catch {}
Note: The state file at server.ts:258 correctly uses mode: 0o600, but the log files do not.
Impact
- Information disclosure:
browse-network.log is created as -rw-r--r-- (world-readable) and contains full request URLs, which may include query-string tokens, session IDs, and API keys
- Symlink/hardlink race: Predictable filenames in shared
/tmp allow a local attacker to pre-place a symlink, causing the server to append log data to an arbitrary file
- CI/shared host risk: On multi-user systems or CI runners, any co-tenant can read browsing activity
Observed Permissions
/tmp/browse-server.json → -rw------- (correct)
/tmp/browse-network.log → -rw-r--r-- (world-readable — vulnerable)
Suggested Fix
- Create a private runtime directory with
fs.mkdtempSync() and mode 0o700, place all state/log files inside it
- Use
O_CREAT | O_EXCL open flags (or equivalent) to avoid following pre-existing symlinks
- Set explicit
0o600 permissions on log files, matching the state file
- Fail hard if directory creation or secure open fails
Severity
Medium — information disclosure of browsing activity (URLs, tokens) to local users via world-readable log files
Summary
The Browse server uses fixed, predictable paths in
/tmpfor log files and creates them with default (world-readable) permissions, leaking browsing activity to any local user.Affected Code
browse/src/server.ts:37-38— Predictable log paths:browse/src/server.ts:52,63— Log files written with default permissions:browse/src/server.ts:202-203— Old logs deleted with unlink (symlink race window):Note: The state file at
server.ts:258correctly usesmode: 0o600, but the log files do not.Impact
browse-network.logis created as-rw-r--r--(world-readable) and contains full request URLs, which may include query-string tokens, session IDs, and API keys/tmpallow a local attacker to pre-place a symlink, causing the server to append log data to an arbitrary fileObserved Permissions
Suggested Fix
fs.mkdtempSync()and mode0o700, place all state/log files inside itO_CREAT | O_EXCLopen flags (or equivalent) to avoid following pre-existing symlinks0o600permissions on log files, matching the state fileSeverity
Medium — information disclosure of browsing activity (URLs, tokens) to local users via world-readable log files