Skip to content

fix(db): hardenize 2 SECURITY DEFINER functions — RLS-002#88

Merged
adm01-debug merged 1 commit into
mainfrom
fix/rls-002-security-definer-hardening
May 22, 2026
Merged

fix(db): hardenize 2 SECURITY DEFINER functions — RLS-002#88
adm01-debug merged 1 commit into
mainfrom
fix/rls-002-security-definer-hardening

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 22, 2026

Summary

Fix do achado RLS-002 (🟡 MÉDIO) da auditoria back-end sênior. Advisor authenticated_security_definer_function_executable flaggou 4 funções; análise detalhada determinou ações distintas:

Hardening (info disclosure cross-user)

Função Risco Fix
is_admin_or_above(_user_id) Qualquer authenticated podia chamar is_admin_or_above(other_user_id) via PostgREST RPC e descobrir se outro user é admin Guard: só self ou dev pode chamar com _user_id diferente de auth.uid(); senão RAISE EXCEPTION 'forbidden' USING ERRCODE='42501'
is_coord_or_above(_user_id) idem Mesma lógica

Mantém assinatura idêntica → uso dentro de RLS continua igual (is_admin_or_above(auth.uid()) passa).

Documentadas como intencionais (sem ação)

Função Justificativa
can_access_quote(_quote_id) Avalia 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 RLS
org_has_any_members(_org_id) Boolean único — leak material mínimo. Usado no fluxo de boot de primeira org
check_login_rate_limit(_email, _ip) Anon-callable intencional — precisa ser chamado ANTES de login

COMMENT ON FUNCTION adicionado em cada uma documentando a decisão.

Aplicação em PROD

Migration aplicada via apply_migration MCP — {"success":true}. As funções continuam compatíveis com todas as policies RLS existentes (mesma assinatura, mesmo retorno).

Test plan

  • Migration aplicada em PROD
  • Próximo get_advisors({type:'security'}) deve mostrar advisor com level: WARN mantido (advisor não conhece o guard interno), mas a info disclosure real está mitigada
  • Teste manual: usuário agente chamando /rest/v1/rpc/is_admin_or_above com _user_id de outro user deve receber 403 (PostgREST traduz ERRCODE 42501 para 403)
  • Teste manual: usuário dev chamando /rest/v1/rpc/is_admin_or_above com qualquer _user_id deve funcionar normalmente
  • RLS policies que chamam is_admin_or_above(auth.uid()) continuam funcionando

https://claude.ai/code/session_011Lgxm1NZGmAztRSvZHX9U3


Generated by Claude Code


Summary by cubic

Hardened two SECURITY DEFINER functions to stop cross-user role checks and prevent info disclosure (RLS-002). Other flagged functions are documented as intentionally exposed.

  • Bug Fixes

    • Added guard to public.is_admin_or_above(_user_id) and public.is_coord_or_above(_user_id): if _user_id != auth.uid() and caller is not dev, raise 42501 (403 in PostgREST).
    • Kept signatures and SECURITY DEFINER unchanged, so RLS calls like is_admin_or_above(auth.uid()) still work.
  • Migration

    • No client changes.
    • Non-dev users now get 403 when calling /rest/v1/rpc/is_admin_or_above or /rest/v1/rpc/is_coord_or_above with another user’s ID.

Written for commit 372e1c0. Summary will update on new commits. Review in cubic

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
Copilot AI review requested due to automatic review settings May 22, 2026 09:36
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Building Building Preview, Comment May 22, 2026 9:36am

@supabase
Copy link
Copy Markdown

supabase Bot commented May 22, 2026

Updates to Preview Branch (fix/rls-002-security-definer-hardening) ↗︎

Deployments Status Updated
Database ⚠️ Fri, 22 May 2026 09:39:19 UTC
Services ⚠️ Fri, 22 May 2026 09:39:19 UTC
APIs ⚠️ Fri, 22 May 2026 09:39:19 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Fri, 22 May 2026 09:39:46 UTC
Migrations ⏸️ Fri, 22 May 2026 09:36:55 UTC
Seeding ⏸️ Fri, 22 May 2026 09:36:55 UTC
Edge Functions ⏸️ Fri, 22 May 2026 09:36:55 UTC

❌ Branch Error • Fri, 22 May 2026 09:39:46 UTC

unexpected status 400: {"message":"Resource has been removed"}
unexpected status 400: {"message":"Resource has been removed"}
unexpected status 400: {"message":"Resource has been removed"}
unexpected status 400: {"message":"Resource has been removed"}

⚠️ Warning — Service health check failed


View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cb82dc25-6980-45f8-80bd-63ecdb4b35b1

📥 Commits

Reviewing files that changed from the base of the PR and between f6e6cf4 and 372e1c0.

📒 Files selected for processing (1)
  • supabase/migrations/20260522030000_rls_002_security_definer_hardening.sql

Walkthrough

Migration SQL endurece duas funções SECURITY DEFINER (is_admin_or_above e is_coord_or_above) adicionando verificação de autorização que bloqueia consultas cross-user para callers sem role dev. Documenta intenção via comentários em cinco funções públicas de RLS e rate-limit.

Changes

RLS Security Definer Hardening

Layer / File(s) Summary
Security Definer authorization guard & documentation
supabase/migrations/20260522030000_rls_002_security_definer_hardening.sql
is_admin_or_above e is_coord_or_above adicionam guarda que lança erro 42501 quando _user_id != auth.uid() e caller não possui role dev. Ambas mantêm retorno para is_supervisor_or_above(_user_id). Migration documenta intenção de can_access_quote, org_has_any_members, check_login_rate_limit, e as próprias funções hardening.

🎯 3 (Moderate) | ⏱️ ~25 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/rls-002-security-definer-hardening

Comment @coderabbitai help to get the list of available commands and usage tips.

@adm01-debug adm01-debug merged commit 5684faf into main May 22, 2026
15 of 21 checks passed
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

@adm01-debug adm01-debug review requested due to automatic review settings May 22, 2026 10:00
@adm01-debug adm01-debug deleted the fix/rls-002-security-definer-hardening branch May 24, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants