Repository navigation
Lock down SECURITY DEFINER functions, privileged columns and login redirects - #163
Merged
Merged
Conversation
…directs - Revoke 11 internal SECURITY DEFINER functions (call-analysis claim, cron cleanups, system chat messages, agent join with owner id, effective plan, monthly usage, autoblog bump, backup-host promotion, auth trigger) from anon/authenticated; service role keeps them. - start_media_session: only the room's host may publish (any signed-in user could make themselves current host of any room). - New functions are no longer executable by PUBLIC/anon/authenticated by default; browser RPCs need an explicit GRANT. - Pin privileged columns behind the update-own policies: participant role, kind, agent owner, backup host, un-leave; session channel/org/team, creator and notify/recording stamps; profile email and created_at. Drop the direct session_participants INSERT policy (joins go through join_session, which enforces plan seat caps). - Login and auth callback redirects rejected '//host' but not '/\\host', which the URL parser reads as another origin. Shared sameOriginPath() now rejects backslashes and control characters and checks the origin. Migration applied by hand on dev2 (backup taken first). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ThreatCrush Security Scan50 finding(s) HIGH/CRITICAL: 4 | MEDIUM: 28 | LOW: 18
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security audit 2026-10-26. 87 SECURITY DEFINER functions in
publicwere executable by anon/authenticated.Dangerous ones fixed
claim_call_analysis(anyone could claim queued call analyses and read the row),send_system_message(anon could post "system" messages with any name into any room),join_session_as_agent(caller-chosenp_owner_id),user_effective_plan/get_user_monthly_usage(other users' plan and usage),cleanup_expired_rooms,mark_stale_participants,prune_meeting_reminders,auto_promote_backup_host,bump_autoblog_integration,handle_new_user. All callers are cron, triggers or service-role routes.start_media_session: any signed-in user could make themselves current host of any room. Now host only.grant execute ... to anon, authenticated.role/kind/agent owner/backup host/un-leave, sessionchannel_id/org_id/team_id/creator_id/notify+recording stamps, profileemail/created_at. Dropped the directsession_participantsINSERT policy (unused by the app; it let users seat themselves past the plan caps)./auth/callback?next=and the login?redirect=accepted/\evil.com, which the URL parser resolves tohttps://evil.com/. NewsameOriginPath()with tests.Migration applied by hand on dev2 (schema backup first); live check with anon key and throwaway users: internal RPCs return 42501, host start/create/join/agent join still work, B cannot hijack, cannot self-promote, cannot insert, plan/email pinned. Remaining exposed: 75, all scoped to
auth.uid()or public read-only data.🤖 Generated with Claude Code