Implement security audit fixes (M1, M2, L1-L5, I1) #1

Merged
hannah-vernon merged 1 commit from feature/security-hardening into dev 2026-06-11 17:32:16 -05:00

What does this PR do?

Implements all fixes recommended by the AI security audit (report findings M1, M2, L1-L5, I1). The audit found 0 Critical/High issues against this local single-user app; this PR closes the 2 Medium, 5 Low, and 1 Info items.

FileTailer (M1, L4)

  • Chunked bounded reads (1 MiB per read) and a capped in-progress line buffer, so a very large append or a file with no line breaks cannot exhaust memory.
  • IO / access errors are surfaced via a new LastError property instead of being swallowed.

FolderTailer (M2, L1, L2, L3, L4)

  • Event-driven discovery with a throttled full rescan (2 s) instead of a full recursive re-enumeration every 250 ms under lock.
  • Directory enumeration and file reads moved outside the lock so a large or deep tree cannot block the poll loop.
  • 4096 file cap per window.
  • Volatile cross-thread flags.
  • Recursive scans skip reparse points (junctions / symlinks) so enumeration stays inside the chosen tree.
  • Regex matching uses a 250 ms timeout.
  • Non-fatal conditions raised via a new Notice event, with de-duplication.

FolderWindow (L5, L4)

  • Persisted window bounds are clamped to the virtual screen with a minimum size before being applied.
  • Subscribes to FolderTailer.Notice and shows messages in the status bar; the start task is observed for faults.

SettingsService (I1)

  • Atomic File.Move replace instead of Copy + Delete when saving settings.

Housekeeping

  • Removed __tailtest harness files that were accidentally committed in the initial commit, and added the folder to .gitignore.
  • Documented the new limits (file cap, symlink handling, bounded memory, status-bar notices) in README.md.

How was this tested?

  • dotnet build Tayler.slnx -c Debug - 0 errors, 0 warnings (WarningsAsErrors is active; -c Release builds clean too).
  • Throwaway harness compiling the actual FileTailer / FolderTailer sources: 11/11 checks passed (initial lines, append follow, partial-line reassembly, truncation reset, initial-lines=0 follow-only, folder discovery of new files, glob filtering). Harness removed after the run.

Checklist

  • I have read the Contributing Guide
  • Changes are focused - one logical change per PR
  • Documentation updated (README limits section)
  • New dependencies are MIT/Apache-2.0 and security-vetted (no new dependencies)
  • No commented-out code or debug leftovers
## What does this PR do? Implements all fixes recommended by the AI security audit (report findings M1, M2, L1-L5, I1). The audit found 0 Critical/High issues against this local single-user app; this PR closes the 2 Medium, 5 Low, and 1 Info items. ### FileTailer (M1, L4) - Chunked bounded reads (1 MiB per read) and a capped in-progress line buffer, so a very large append or a file with no line breaks cannot exhaust memory. - IO / access errors are surfaced via a new `LastError` property instead of being swallowed. ### FolderTailer (M2, L1, L2, L3, L4) - Event-driven discovery with a throttled full rescan (2 s) instead of a full recursive re-enumeration every 250 ms under lock. - Directory enumeration and file reads moved outside the lock so a large or deep tree cannot block the poll loop. - 4096 file cap per window. - Volatile cross-thread flags. - Recursive scans skip reparse points (junctions / symlinks) so enumeration stays inside the chosen tree. - Regex matching uses a 250 ms timeout. - Non-fatal conditions raised via a new `Notice` event, with de-duplication. ### FolderWindow (L5, L4) - Persisted window bounds are clamped to the virtual screen with a minimum size before being applied. - Subscribes to `FolderTailer.Notice` and shows messages in the status bar; the start task is observed for faults. ### SettingsService (I1) - Atomic `File.Move` replace instead of Copy + Delete when saving settings. ### Housekeeping - Removed `__tailtest` harness files that were accidentally committed in the initial commit, and added the folder to `.gitignore`. - Documented the new limits (file cap, symlink handling, bounded memory, status-bar notices) in `README.md`. ## How was this tested? - [x] `dotnet build Tayler.slnx -c Debug` - 0 errors, 0 warnings (WarningsAsErrors is active; `-c Release` builds clean too). - [x] Throwaway harness compiling the actual `FileTailer` / `FolderTailer` sources: 11/11 checks passed (initial lines, append follow, partial-line reassembly, truncation reset, initial-lines=0 follow-only, folder discovery of new files, glob filtering). Harness removed after the run. ## Checklist - [x] I have read the [Contributing Guide](../CONTRIBUTING.md) - [x] Changes are focused - one logical change per PR - [x] Documentation updated (README limits section) - [x] New dependencies are MIT/Apache-2.0 and security-vetted (no new dependencies) - [x] No commented-out code or debug leftovers
Address findings from the AI security audit:

- M1/L4 (FileTailer): chunked bounded reads (1 MiB) and a capped
  in-progress line buffer so a very large append or a newline-free file
  cannot exhaust memory; surface IO/access errors via LastError instead
  of swallowing them.
- M2/L1/L2/L3/L4 (FolderTailer): event-driven discovery with a throttled
  full rescan; enumeration and file reads moved outside the lock; 4096
  file cap; volatile cross-thread flags; recursive scans skip reparse
  points (junctions / symlinks); regex matching uses a 250 ms timeout;
  non-fatal conditions raised via a new Notice event with de-duplication.
- L5 (FolderWindow): clamp persisted window bounds to the virtual screen
  and enforce a minimum size before applying.
- L4 (FolderWindow): subscribe to FolderTailer.Notice and surface
  messages in the status bar; observe the Start task for faults.
- I1 (SettingsService): atomic File.Move replace instead of Copy+Delete.

Also remove accidentally committed __tailtest harness files, ignore the
folder, and document the new limits in README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
hannah-vernon/tayler-log-tailer!1
No description provided.