[Bounty $200] security: slack/clickup/twitter transcript webhooks + slack tools trust client-supplied uid — unauthenticated writes into victim workspaces
Summary
Real-time transcript webhooks and chat-tool routes in three apps bind uid straight from the request with no authentication, then act on that uid's stored OAuth credentials:
omi-slack-app/webhook— attacker transcript segments get posted as messages into the victim's connected Slack channel. The/api/send_message,/api/search_messages,/api/search_channelschat tools take uid in the JSON body and act directly with the victim's token (send/search as them).omi-clickup-app/webhook— attacker transcript segments create tasks in the victim's ClickUp list.omi-twitter-app/webhook— attacker transcript segments trigger tweets from the victim's account.
Anyone who knows or guesses a uid can push arbitrary transcript content (or direct tool calls) that the victim's connected workspace acts on — unauthenticated write/spam path into third-party accounts. Same defect class as the zapier fix in #14428/#14429 and the paid mentor fix (#13685); these apps were missed by both and by the umbrella uid-as-auth PR #13463.
Fix
Each app gets the mentor-pattern guard module (<app>_webhook_auth.py): a shared-secret check (Authorization: Bearer or <app>_webhook_token query param, <APP>_WEBHOOK_SECRET env). /webhook routes bind uid via Depends(require_<app>_webhook_auth); slack's body-uid /api/* tools get require_slack_tool_auth (caller authentication only). Fail-closed 503 when unconfigured, 401 on missing/wrong token, 422 on blank uid.
Scope note: backend-invoked routes only — the pattern of the merged mentor fix. The browser-called settings routes share the fleet-wide uid model tracked by #13463.
PR with fix + tests: #14447. cc @kodjima33 @Git-on-my-level
Source: BasedHardware/omi