From bba6a7cce3cdc2da04efd03dda411b93a3e3dffc Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:36:34 -0700 Subject: [PATCH] security(browser): restrict cookie-import staging file permissions The cookie-import staging directory under userData held a full copy of the browser cookie database (session tokens). It was created with the default umask (world-readable dir + 0644 file) and, in the post-restart import handoff path, persists on disk across a restart. On a shared/multi-user machine another local account could read the staged cookies. Create the staging dir 0700 (and chmod it, since recursive mkdir leaves an existing dir's mode untouched) and the copied DB 0600. Co-authored-by: Orca --- src/main/browser/browser-cookie-import.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/browser/browser-cookie-import.ts b/src/main/browser/browser-cookie-import.ts index 7079141f4e6..8a26e657794 100644 --- a/src/main/browser/browser-cookie-import.ts +++ b/src/main/browser/browser-cookie-import.ts @@ -5,6 +5,7 @@ import { execFileSync } from 'node:child_process' import { createDecipheriv, pbkdf2Sync, randomUUID } from 'node:crypto' import { appendFileSync, + chmodSync, copyFileSync, existsSync, mkdtempSync, @@ -1515,8 +1516,13 @@ export async function importCookiesFromBrowser( `Cookies-${partitionSegment}-${Date.now()}-${randomUUID()}` ) try { - mkdirSync(stagingDir, { recursive: true }) + // Why: the staged copy is a full cookie DB (session tokens). Lock the dir + // and file to the current user so another local account cannot read them — + // recursive mkdir leaves an existing dir's mode untouched, so set it too. + mkdirSync(stagingDir, { recursive: true, mode: 0o700 }) + chmodSync(stagingDir, 0o700) copyFileSync(liveCookiesPath, stagingCookiesPath) + chmodSync(stagingCookiesPath, 0o600) } catch { rmSync(tmpDir, { recursive: true, force: true }) return { ok: false, reason: 'Could not create staging cookie database.' }