Skip to content

fix: critical security and concurrency fixes (C1-H16, Phase 1-3) - #165

Merged
Patel230 merged 14 commits into
mainfrom
fix/critical-security-and-concurrency
Aug 2, 2026
Merged

fix: critical security and concurrency fixes (C1-H16, Phase 1-3)#165
Patel230 merged 14 commits into
mainfrom
fix/critical-security-and-concurrency

Conversation

@Patel230

@Patel230 Patel230 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the full audit remediation plan for the deep code review: 8 CRITICAL, 16 HIGH, and selected MEDIUM findings. Closes the sandbox fail-open gap, fixes concurrency/data-loss bugs in sessions and background agents, hardens permission bypass and Guardian injection, adds daemon rate limiting and the documented /v1/cancel endpoint, and fixes a dead self-improvement loop.

Changes

  • engine: snapshot distiller state before async goroutine (C7); BackgroundAgentPool parent context + Stop() cancellation (C8); Finalize now populates ToolsUsed/FilesChanged so the self-improvement loop actually triggers (H1); emergency-compact before overflow retry (H3); structural truncation of tool output (M)
  • tool/sandbox: schema-driven ValidateToolInput wired into Registry.Execute with explicit required fields (H5); sandbox fail-closed already landed in cf16250/9efd879 (C1-C6)
  • permissions: destructive commands hard-denied even with bypass; bypass path audited via slog (H6); Guardian uses <tool_data> structural isolation + 0.8 threshold instead of blocklist sanitizer (H7); Bash:git * auto-allow narrowed to safe git subcommands (M)
  • daemon: global concurrency semaphore (503), per-IP rate limits (429), POST /v1/cancel implemented + documented in openapi/threat model (H9/H10)
  • session: context threaded through SQLiteStore (H12); SnapshotStore mutex (H13); ConversationGraph fsync (H14); streaming session search (M); corrupt-line logging (M)
  • observability: OTEL span errors redacted (incl. sk-ant-api keys) (H15); telemetry now opt-in only (M)
  • acp/provider/config: ACP session cap + teardown (H11); gateway init retry (H8); settings cache invalidation on save (M)

Testing

  • go test -race ./... — all packages pass
  • go vet ./..., golangci-lint run ./... — clean
  • govulncheck ./... — no vulnerabilities in called code
  • All 8 boundary scripts pass; lefthook pre-push hooks (test, vet, govulncheck, boundaries) green on push
  • New tests: background agent cancellation, lifecycle finalize, gateway singleton retry, permission engine bypass, guardian injection, daemon cancel/rate-limit, SQLite ctx cancellation, snapshot race, span redaction, userns remap

Patel230 added 14 commits August 2, 2026 06:25
The Bash tool checked sandbox.Available() before calling WrapCommand.
When no backend was available but a mode was configured, the command
fell through to unsandboxed host execution — contradicting the
documented 'fail closed' promise.

C1: Foreground Bash — remove Available() guard, always call
WrapCommand, propagate its error as fail-closed.
C2: Background Bash — apply WrapCommand before startBackgroundBash,
which now accepts the wrapped execName/execArgs.
C3: PowerShell — add ModeFromContext + WrapCommand, fail-closed.

Tests: bash_sandbox_test.go + powershell_test.go cover fail-closed
for ModeWorkspace/ModeStrict, no-regression for ModeOff, and
sandbox wrapping for background bash.
Three resource leaks in mission mode are fixed:

C4: Worktree leak on mission cancellation. The cleanup defer used the
mission context, which was already cancelled when the mission was
aborted — so 'git worktree remove' was killed before it could run.
Now uses a detached context (context.Background + 30s timeout) via
removeWorktreeDetached.

C5: Temp-dir leak when git worktree add fails. createWorktree calls
mktemp -d then git worktree add; if git failed, the temp dir was
never removed. Now calls os.RemoveAll before returning the error.

C6: Mission temp dirs never cleaned up. Every mission run created
/tmp/hawk-missions/{ID}/ with no cleanup. Added Mission.Cleanup()
and wired it into cmd/mission.go via defer.

Also: removeWorktree now does best-effort os.RemoveAll on the
directory itself if git worktree remove fails, so the mktemp dir
doesn't leak even when git metadata is already gone.

Tests: worker_cleanup_test.go covers all three fixes.
@Patel230
Patel230 merged commit 0ee339b into main Aug 2, 2026
23 checks passed
@Patel230
Patel230 deleted the fix/critical-security-and-concurrency branch August 2, 2026 16:48
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