← Back to PRs

#11873: fix: eliminate TOCTOU race in readExecApprovalsSnapshot

by Yida-Dev open 2026-02-08 13:16 View on GitHub →
stale
## Summary - `readExecApprovalsSnapshot()` used `existsSync()` followed by `readFileSync()` without wrapping the read in a try-catch - If the approvals file is deleted between the two calls (e.g. by a concurrent reset), `readFileSync` throws an unhandled ENOENT exception - Replaces the `existsSync` guard with a try-catch around `readFileSync`, matching the pattern already used by `loadExecApprovals()` in the same file (line 255) ## Test plan - [x] All 44 existing `exec-approvals.test.ts` tests pass - [x] No behavioral change for normal operation — only the error path is now handled gracefully Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR updates `readExecApprovalsSnapshot()` to avoid a TOCTOU race by removing the `existsSync()` pre-check and instead wrapping `readFileSync()` in a `try/catch`, returning a normalized empty approvals file when the file is missing/unreadable. This aligns the snapshot reader’s error handling with the existing `loadExecApprovals()` pattern in `src/infra/exec-approvals.ts`. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - Change is narrowly scoped to error handling around reading the approvals file, removes an actual TOCTOU failure mode, and preserves existing behavior by returning the same normalized empty snapshot on read failure; no new side effects are introduced in the normal path. - No files require special attention <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs