fix(db): hardenize 2 SECURITY DEFINER functions — RLS-002#88
Conversation
Achado RLS-002 da auditoria back-end sênior 2026-05-22 (PR #55). Advisor `authenticated_security_definer_function_executable` flaggou 4 funções; análise detalhada determinou ações distintas: Hardening (info disclosure cross-user): - is_admin_or_above(_user_id) → guard: só self ou dev - is_coord_or_above(_user_id) → guard: só self ou dev Documentadas como intencionais (sem ação adicional): - can_access_quote(_quote_id) → avalia auth.uid() interno; safe - org_has_any_members(_org_id) → boolean único; leak material mínimo - check_login_rate_limit(_email, _ip) → anon-callable intencional Migration aplicada em PROD via apply_migration. Mantém SECURITY DEFINER + assinatura idêntica → uso em RLS continua igual. https://claude.ai/code/session_011Lgxm1NZGmAztRSvZHX9U3
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Updates to Preview Branch (fix/rls-002-security-definer-hardening) ↗︎
Tasks are run on every commit but only new migration files are pushed.
❌ Branch Error • Fri, 22 May 2026 09:39:46 UTC View logs for this Workflow Run ↗︎. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughMigration SQL endurece duas funções ChangesRLS Security Definer Hardening
🎯 3 (Moderate) | ⏱️ ~25 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Summary
Fix do achado RLS-002 (🟡 MÉDIO) da auditoria back-end sênior. Advisor
authenticated_security_definer_function_executableflaggou 4 funções; análise detalhada determinou ações distintas:Hardening (info disclosure cross-user)
is_admin_or_above(_user_id)is_admin_or_above(other_user_id)via PostgREST RPC e descobrir se outro user é admin_user_iddiferente deauth.uid(); senãoRAISE EXCEPTION 'forbidden' USING ERRCODE='42501'is_coord_or_above(_user_id)Mantém assinatura idêntica → uso dentro de RLS continua igual (
is_admin_or_above(auth.uid())passa).Documentadas como intencionais (sem ação)
can_access_quote(_quote_id)auth.uid()internamente — não vaza info de quotes do próprio usuário; só retorna boolean para quote ao qual o caller já tem acesso via RLSorg_has_any_members(_org_id)check_login_rate_limit(_email, _ip)COMMENT ON FUNCTIONadicionado em cada uma documentando a decisão.Aplicação em PROD
Migration aplicada via
apply_migrationMCP —{"success":true}. As funções continuam compatíveis com todas as policies RLS existentes (mesma assinatura, mesmo retorno).Test plan
get_advisors({type:'security'})deve mostrar advisor comlevel: WARNmantido (advisor não conhece o guard interno), mas a info disclosure real está mitigadaagentechamando/rest/v1/rpc/is_admin_or_abovecom_user_idde outro user deve receber 403 (PostgREST traduz ERRCODE 42501 para 403)devchamando/rest/v1/rpc/is_admin_or_abovecom qualquer_user_iddeve funcionar normalmenteis_admin_or_above(auth.uid())continuam funcionandohttps://claude.ai/code/session_011Lgxm1NZGmAztRSvZHX9U3
Generated by Claude Code
Summary by cubic
Hardened two
SECURITY DEFINERfunctions to stop cross-user role checks and prevent info disclosure (RLS-002). Other flagged functions are documented as intentionally exposed.Bug Fixes
public.is_admin_or_above(_user_id)andpublic.is_coord_or_above(_user_id): if_user_id!=auth.uid()and caller is notdev, raise42501(403 inPostgREST).SECURITY DEFINERunchanged, so RLS calls likeis_admin_or_above(auth.uid())still work.Migration
/rest/v1/rpc/is_admin_or_aboveor/rest/v1/rpc/is_coord_or_abovewith another user’s ID.Written for commit 372e1c0. Summary will update on new commits. Review in cubic