From 59885e82cdb25f540ddcf366800f84e4e11c51b3 Mon Sep 17 00:00:00 2001 From: "Jiaxiao (mossaka) Zhou" Date: Thu, 12 Feb 2026 20:14:17 +0000 Subject: [PATCH] fix: eliminate TOCTOU race conditions in ssl-bump.ts initSslDb Replace check-then-act pattern (existsSync + writeFileSync) with atomic file creation using the 'wx' flag (O_WRONLY | O_CREAT | O_EXCL). This eliminates time-of-check-time-of-use race conditions where a file could be created between the existence check and the write operation. Fixes #174, #175. Co-Authored-By: Claude Opus 4.6 --- src/ssl-bump.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/ssl-bump.ts b/src/ssl-bump.ts index 5bd6dafe..55fe8069 100644 --- a/src/ssl-bump.ts +++ b/src/ssl-bump.ts @@ -144,13 +144,20 @@ export async function initSslDb(workDir: string): Promise { } // Create index.txt (empty file for certificate index) - if (!fs.existsSync(indexPath)) { - fs.writeFileSync(indexPath, '', { mode: 0o600 }); + // Use 'wx' flag (O_WRONLY | O_CREAT | O_EXCL) for atomic create-if-not-exists, + // avoiding TOCTOU race between existsSync and writeFileSync + try { + fs.writeFileSync(indexPath, '', { flag: 'wx', mode: 0o600 }); + } catch (e: unknown) { + if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e; } // Create size file (tracks current DB size, starts at 0) - if (!fs.existsSync(sizePath)) { - fs.writeFileSync(sizePath, '0\n', { mode: 0o600 }); + // Same atomic pattern to avoid TOCTOU race condition + try { + fs.writeFileSync(sizePath, '0\n', { flag: 'wx', mode: 0o600 }); + } catch (e: unknown) { + if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e; } logger.debug(`SSL certificate database initialized at: ${sslDbPath}`);