Skip to content

[Security] Insecure /tmp file handling with world-readable logs #19

@fredluz

Description

@fredluz

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

  1. 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
  2. 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
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions