Skip to content

fix(security): correctness & security hardening from full code review#1

Merged
Wixely merged 1 commit into
mainfrom
fix/code-review
Jul 15, 2026
Merged

fix(security): correctness & security hardening from full code review#1
Wixely merged 1 commit into
mainfrom
fix/code-review

Conversation

@Wixely

@Wixely Wixely commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Full correctness + security code review of the project. All fixes on fix/code-review; Release build clean, 100 tests pass (2 new regression tests).

Fixed — high severity

  • IMAP read-only data-lossEXAMINE + STORE \Deleted + CLOSE deleted mail from a read-only-opened mailbox. Writability is now tracked per-selection and gates STORE \Deleted / EXPUNGE / CLOSE-expunge.
  • IMAP slot exhaustion (slowloris) — no read timeouts; idle/silent connections held session slots forever. Added 60s pre-auth and 30min authenticated/IDLE timeouts.
  • IMAP silent TLS to plaintext fallback — a configured-but-missing cert was swallowed and the server came up in plaintext. Now fails fast at startup.
  • JSON store crash-dedup relied on NFS mtime — replaced with a state-aware tie-break; added a GUID fallback for folder-name collisions.

Fixed — medium severity

  • Resolver torn read + stale negative cachevolatile record ref for the catch-all cache; IAliasResolver.Invalidate() wired to alias create/delete so new aliases accept mail immediately (was up to 30s late).
  • SQLite gate could hang forever — bounded the exclusive-connection gate wait (60s) -> clear TimeoutException instead of a silent hang.
  • IMAP hardening — brute-force cap, credential redaction in logs, literal-size caps, LIST regex match-timeout (ReDoS guard).

Behavior change (review before merge)

  • Auth cookie SameSite=Lax -> Strict — closes the residual CSRF window on route-only admin POSTs. Trade-off: following an external link into the UI shows the login page until you navigate within the app. Revert the one line if the UX is undesirable.

Reviewed, deliberately unchanged (false positives)

SMTP governor > (correct), ImapFormat.BodyStart bound (correct), reindexer catch-all routing (correct for recovery), message-HTML CSP (already airtight via default-src 'none' + sandbox=""), streaming FETCH literals (perf note, not a bug).

🤖 Generated with Claude Code

IMAP (highest-risk hand-rolled code):
- fix read-only data-loss: EXAMINE + STORE \Deleted + CLOSE deleted mail
  from a read-only-opened mailbox; track writability per selection and gate
  STORE \Deleted / EXPUNGE / CLOSE-expunge on it
- add pre-auth (60s) and authenticated/IDLE (30min) read timeouts so dead
  connections no longer exhaust the session slots (slowloris)
- fail fast on a configured-but-missing TLS cert instead of silently falling
  back to plaintext credentials
- brute-force cap, credential redaction in logs, literal-size caps, and a
  match timeout on the LIST wildcard->regex conversion

Data layer:
- JSON store: replace NFS-unreliable mtime dedup with a state-aware tie-break;
  add a GUID fallback for folder-name collisions
- resolver: fix torn read of the catch-all cache (volatile record ref) and
  add Invalidate() wired to alias create/delete so a new alias accepts mail
  immediately instead of after the 30s negative-cache TTL
- SQLite: bound the exclusive-connection gate wait (60s) so a re-entrant or
  stuck open throws instead of hanging the app forever

Web:
- tighten the auth cookie to SameSite=Strict (closes the residual CSRF window
  on the route-only admin POSTs)

Tests: add regression coverage for the IMAP read-only guard and the resolver
cache invalidation. Full suite green (100 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Wixely
Wixely merged commit b139e25 into main Jul 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant