fix(db): restore message sending, broken by the SECURITY DEFINER revoke sweep - #255
Merged
Merged
Conversation
…ke sweep Every INSERT into public.messages has been failing with "permission denied for function calculate_message_expiration" since #247. The newest row in `messages` is 2026-08-13 and #247 landed on 2026-08-14: nobody has been able to send a message for three days. `set_message_expiration` is the only trigger on `messages` that is not SECURITY DEFINER, so its inner call ran with the writer's privileges. When the sweep revoked EXECUTE, `authenticated` lost the grant 20260203114500 had given it, the trigger raised, and the raise took the INSERT with it. Making the trigger SECURITY DEFINER matches its sibling `trigger_create_message_status`, which was unaffected for exactly this reason, and fixes the outage without re-exposing calculate_message_expiration to client roles the way a plain GRANT back would have. Already applied to production; verified with a rolled-back INSERT as a simulated authenticated session. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ThreatCrush Security Scan91 finding(s) HIGH/CRITICAL: 5 | MEDIUM: 10 | LOW: 76
…and 41 more. Full results in the Security tab. 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.
Message sending has been completely broken in production for three days. Already applied to prod and verified; this commits the migration so the repo matches.
What happened
Every
INSERTintopublic.messagesfailed with:set_message_expirationis the only trigger onmessagesthat is notSECURITY DEFINER, so its inner call ran with the writer's privileges. When #247 sweptEXECUTEoff the SECURITY DEFINER functions,authenticatedlost the grant that20260203114500had explicitly given it. The trigger raised, and the raise took the whole INSERT with it.Evidence
messages: 2026-08-13. fix(security): revoke anon EXECUTE on the remaining 41 SECURITY DEFINER fns #247 landed 2026-08-14. Zero messages since.trigger_create_message_statusis alreadySECURITY DEFINERand was unaffected — for precisely this reason.The fix
Make
set_message_expirationSECURITY DEFINER, matching its sibling. This restores sending without re-exposingcalculate_message_expirationto client roles, which is what a plainGRANT ... TO authenticatedwould have done.Verified with a rolled-back
INSERTas a simulated authenticated session:insert_ok=t.Lesson for the next revoke sweep
Revoking
EXECUTEis not purely a lock-down. Any function reachable from a non-DEFINER trigger is called with the writer's privileges, so revoking there is a silent write outage. Checkpg_triggerbefore revoking — the failure surfaces as an application 500, not as a security finding.🤖 Generated with Claude Code