From 7a40426d42edd5f382340ca2fca448211a6ba5e5 Mon Sep 17 00:00:00 2001 From: haowei Date: Fri, 17 Jul 2026 14:21:06 +0800 Subject: [PATCH 1/2] fix(security,perf): address deep-audit findings across all components Deep security + performance audit of frontend, gateway/API, infra, MCP, and connector. 19 findings fixed, 2 partial, 3 deferred. All fixes were adversarially re-reviewed; the review's corrections are folded in. Security - approval: gate resolve_permission on membership/admin OR bot-owner and purge stale approval_delegations + RESPOND grants on member removal (#1) - agent_bridge: require bot channel membership in handle_acp_event_frame before any store write / event-log / broadcast (#3) - ratelimit: bound eviction (retain live windows + hard-clear fallback) (#12) - email: never log one-time codes when an email provider is configured (#13) - CSP: add default/script/style/img/font/connect/media-src; allow https images and blob media (#17) - connector: cap self-update downloads, monotonic anti-downgrade guard, bound the loopback pre-auth request body (413) (#14, #24, #15) - workspace: escape LIKE wildcards; files: normalize content_type to a safe allowlist (#22, #23) Performance - auth: run all bcrypt hash/verify on spawn_blocking, incl. admin seed (#2) - db: bounded unread/mention scan (99+), partial index for pending permissions, batched Fleet policy resolution (#6, #7, #5) - gateway: TTL cache for per-trace bot rules, presence roster cache (#8, #9) - frontend: plain-text streaming render + memoized MarkdownRenderer, stable channelFiles memo, offline stream-finalize guard (#10, #11) - connector: Value::take / mem::take to drop redundant deep clones (#20, #21) Deferred (documented): #4 Redis-backed cross-replica limiter (interim: replicaCount=1), #16 httpOnly-cookie session token, #18 Arc fan-out. Verified offline: server cargo check + 172/172 lib tests; connector cargo check + 98/98 tests; mcp-server cargo check; frontend typecheck (changed files clean) + 66/66 vitest. Co-Authored-By: Claude Fable 5 --- deploy/helm/cheers/templates/frontend.yaml | 12 +- frontend/src/components/MarkdownRenderer.tsx | 6 +- frontend/src/features/chat/ChannelView.tsx | 28 ++++- frontend/src/features/chat/MessageItem.tsx | 20 ++-- .../src/acp_adapter.rs | 18 ++- .../src/bridge_runtime/mod.rs | 7 +- .../cheers-acp-connector-rs/src/loopback.rs | 23 ++++ .../src/self_update.rs | 94 +++++++++++++-- ...0049_messages_pending_permission_index.sql | 9 ++ server/src/api/approval.rs | 16 +++ server/src/api/auth.rs | 14 ++- server/src/api/channels.rs | 111 ++++++++++++++---- server/src/api/files.rs | 83 +++++++++++-- server/src/api/fleet.rs | 96 ++++++++++++--- server/src/api/users.rs | 3 +- server/src/api/workspace.rs | 7 +- server/src/domain/acp_policy.rs | 36 +++++- server/src/domain/auth.rs | 6 +- server/src/domain/seed.rs | 5 +- server/src/gateway/presence.rs | 65 ++++++++-- server/src/gateway/ws/agent_bridge.rs | 86 +++++++++++++- server/src/infra/crypto.rs | 24 ++++ server/src/infra/email.rs | 15 ++- server/src/infra/ratelimit.rs | 36 ++++-- 24 files changed, 706 insertions(+), 114 deletions(-) create mode 100644 server/migrations/0049_messages_pending_permission_index.sql diff --git a/deploy/helm/cheers/templates/frontend.yaml b/deploy/helm/cheers/templates/frontend.yaml index a3c14a13..6e1203b6 100644 --- a/deploy/helm/cheers/templates/frontend.yaml +++ b/deploy/helm/cheers/templates/frontend.yaml @@ -16,13 +16,15 @@ data: index index.html; # Security headers (audit M2): clickjacking + MIME-sniff + referrer + a - # minimal CSP. CSP is intentionally narrow (no script-src lockdown) to - # avoid breaking the Vite SPA; tighten with nonces later. No location here - # defines its own add_header, so these inherit to every response. + # hardened CSP. The production Vite build emits only external hashed module + # scripts (no inline