feat(security): atomic writes, input validators, and static analysis tooling#118
Conversation
|
Thanks for splitting this out. I took another careful pass over the PR and found a few things worth addressing before merge:
Verification run locally on the PR head:
|
65dede8 to
a1ad1b4
Compare
|
Thanks for the thorough review. Here's how each issue was addressed in the updated commit ( 1. Atomic overwrite silently downgrades file mode (high) Root cause: passing Fix: open the temp file without a mode argument, then call New regression tests cover:
Both async and sync variants. 2. Fix: replaced the broad 3. Semgrep rule misses Fix: replaced the single 4. Fix: added an inline comment on that entry: 'electron/mcp/server.ts', // added in coordinator-2-mcp-backend; listed here so knip tracks it from the startThe Semgrep/Gitleaks/Knip/dependency-cruiser configs being staged-but-not-wired-to-CI is intentional and called out in the PR description — they land as infrastructure groundwork that the follow-on PRs will wire up. |
a1ad1b4 to
3c04783
Compare
|
Thanks for the updates. I took another pass over the current head (
Verification on the PR head:
|
…tooling atomic.ts / atomic.test.ts - Crash-safe atomic file writes via temp-file + rename - fsync temp file and directory entry for durability - Preserve existing file mode on overwrite; use fchmod after open to set exact mode bits, bypassing process umask - Tests force umask=0o022 in exact-mode cases for CI determinism validation.ts / validation.test.ts - validateBranchName: mirrors git check-ref-format --branch rules (rejects HEAD; accepts FETCH_HEAD/ORIG_HEAD per actual git behaviour) - validateUUID: enforces v4 UUID (version nibble 4, variant nibble 8/9/a/b) Static analysis - .semgrep/filesystem-safety.yml: flag raw writeFileSync in MCP/coordinator paths; pattern-either covers both qualified (fs.writeFileSync) and unqualified forms - .semgrep/electron-security.yml, .semgrep/ipc-auth.yml: IPC auth checks - .dependency-cruiser.cjs: architecture boundary enforcement - .gitleaks.toml: secret-scanning rules - knip.config.ts: dead-export detection; server.ts listed as entry point (lands in coordinator-2-mcp-backend) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3c04783 to
60bdf5a
Compare
|
Thanks for the detailed follow-up. All four issues are addressed in the updated head ( 1. Temp-file mode exposure window (
|
Migrate electron/ipc/register.ts's loose validateBranchName (only rejected empty / leading "-") to the new shared validator from electron/mcp/validation, so the strict git-check-ref-format rules actually run today instead of waiting for later coordinator PRs. Drop the now-unused orphan exemption for validation.ts in .dependency-cruiser.cjs. Default the field name in validateBranchName to "branch" rather than the misleading "baseBranch". Comment .parallel-code/ in .gitignore.
|
Thank you very much! I made some small adjustments after in a seperate commit. Hope this will be a good basis for the rest of the feature. |
Overview
Standalone security utilities and static analysis tooling — no coordinator logic, no UI. This is PR 1 of 4 splitting #100 as requested in the round-4 review.
PR sequence:
coordinator-1-securitycoordinator-2-mcp-backendcoordinator-3-store-ipccoordinator-4-uiPRs 2–4 are stacked on each other; nothing coordinator-related is user-visible until PR 4 adds the
NewTaskDialogcheckbox and Settings toggle.What's in this PR
electron/mcp/atomic.tsCrash-safe file writes via temp file + rename:
fsyncbefore rename for file durability; directoryfsyncafter rename for directory-entry durability (platform-safe catch for Windows/network mounts)electron/mcp/validation.tsvalidateBranchName()— mirrorsgit check-ref-format --branch: rejects shell metacharacters (:,^,~, etc.), double dots, path components starting with., any path component ending in.lock, and other git-illegal patternsvalidateUUID()— enforces v4 UUID (version nibble=4, variant nibble∈{8,9,a,b})Static analysis configs
.semgrep/— rules for unsafe Electron APIs, IPC auth, and unsafefsoperations (scoped toelectron/mcp/**+electron/ipc/register.ts).gitleaks.toml— token/secret leak detection.dependency-cruiser.cjs— architecture lintingknip.config.ts— dead code detectionNote: the static analysis tools (
semgrep,gitleaks,dependency-cruiser,knip) are not yet wired into CI — they require system/devDependency setup that lands in PR 2. Configs are included here as they're used to validate the coordinator code in PR 2.Tests (35 cases)
electron/mcp/validation.test.ts— accepted names, all rejection cases, UUID v4 enforcementelectron/mcp/atomic.test.ts— write, overwrite, mode, no temp-file residueTest plan
npm run typecheck && npm test && npm run lint— all passelectron/mcp/validation.test.tsandelectron/mcp/atomic.test.ts— 35/35🤖 Generated with Claude Code