Skip to content

fix(security): hardening de grants anon + rate-limit no reset de senha (auditoria MCP rodada 2)#299

Merged
adm01-debug merged 3 commits into
mainfrom
claude/epic-faraday-GQILK
May 24, 2026
Merged

fix(security): hardening de grants anon + rate-limit no reset de senha (auditoria MCP rodada 2)#299
adm01-debug merged 3 commits into
mainfrom
claude/epic-faraday-GQILK

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

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

Rodada 2 da auditoria de segurança via MCP

Segue #294 (mojibake, já mergeado). Esta PR aplica as correções de backend seguras e verificadas e documenta a reclassificação honesta dos demais achados.

Verificação read-only antes de agir

Métrica Valor
Tabelas public com RLS desabilitada 0 (de 280)
Políticas anon/public 309
Dessas, irrestritas (USING/CHECK = true) 18 — todas dados não sensíveis (catálogo + kill switches/geo pré-login)

Não há vazamento de dados ativo. Os 373 avisos anon_table_exposed são superfície de API mitigada por RLS. Revogação em massa de grants foi descartada (alto risco, ganho nulo).

Corrigido (migration 20260524210000)

  • REVOKE EXECUTE em cleanup_expired_webhook_request_nonces() e get_public_schema_signatures() para anon+authenticated (não usadas pelo cliente; postgres/service_role mantêm acesso → cron e edge functions intactos).
  • Rate-limit no reset de senha: trigger BEFORE INSERT (SECURITY DEFINER) → máx. 3 solicitações/e-mail/60min em password_reset_requests. Fecha o abuso da política de INSERT irrestrita sem removê-la.
  • SQL validado em transação com ROLLBACK (sem erros, sem persistir).

Reclassificado após investigação (NÃO são defeitos — não alterados)

  • get_quote_token_by_value por anon = lookup por token-segredo do orçamento público (não é enumeração). Mantido.
  • "Preço próximo do limite de validade" em todos os produtos = price-freshness.ts correto; preços do catálogo genuinamente > 30 dias. Remédio = atualização de preços na origem (data ops), não código. Mexer no threshold só mascararia o sinal.
  • Widget "Próximas Datas" do Dashboard = estados loading/erro/vazio corretos; skeleton observado era carregamento transitório.

Requer decisão de produto (não executável com segurança aqui)

  • Kit Maker servindo MOCK_BOXES/MOCK_ITEMS → conectar a dados reais é feature + fonte de dados a definir.
  • Atualização de preços do catálogo (data ops).
  • Rodar get_advisors(performance).

Test plan

  • CI verde
  • Smoke supabase start aplica a migration sem erro
  • (Pós-deploy) confirmar que cron de cleanup_* e edge functions seguem operando; reset de senha bloqueia após 3 tentativas/e-mail/hora

https://claude.ai/code/session_01HjiGVkF3Df9GiFjDbfxDYn


Generated by Claude Code


Summary by cubic

Hardened database access by revoking client execution of internal functions and adding a rate limit to password reset requests. Verified RLS on all public tables; no sensitive data exposure found.

  • Migration
    • Revoked EXECUTE on cleanup_expired_webhook_request_nonces() and get_public_schema_signatures() for anon and authenticated; postgres/service_role keep access for cron/edge.
    • Added BEFORE INSERT trigger (SECURITY DEFINER) to limit password resets to 3 requests per email per 60 minutes in password_reset_requests.

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

claude added 3 commits May 24, 2026 20:40
…d via MCP

Varredura do sistema em produção (promogifts.com.br) via navegador MCP,
captura de rede e advisors do Supabase. Achado principal: dupla codificação
UTF-8 (Latin-1) corrompendo texto visível em login, simulador de preços,
Kit Maker e formulários admin (500 ocorrências). Reversão seletiva preserva
caracteres legítimos; sem mudança estrutural de código.

Relatório completo em audit/AUDITORIA_FRONTEND_MCP_2026-05-24.md (backend RLS,
funções SECURITY DEFINER expostas a anon, Kit Maker em mock, price-freshness).

https://claude.ai/code/session_01HjiGVkF3Df9GiFjDbfxDYn
…ed e adiciona rate-limit no reset de senha

Rodada 2 da auditoria MCP. Verificação read-only confirmou RLS ativa em todas
as 280 tabelas (0 desabilitadas) e que apenas 18 das 309 políticas anon/public
são irrestritas — todas de dados não sensíveis. Sem vazamento ativo.

Correções seguras:
- REVOKE EXECUTE em cleanup_expired_webhook_request_nonces() e
  get_public_schema_signatures() para anon/authenticated (não usadas pelo
  cliente; postgres/service_role mantêm acesso p/ cron e edge functions).
- Trigger BEFORE INSERT (SECURITY DEFINER) limita reset de senha a 3/e-mail/60min,
  fechando o abuso da política de INSERT irrestrita sem removê-la.

SQL validado em transação com ROLLBACK. Relatório atualizado com a reclassificação
dos demais achados (price-freshness e widget = não-defeitos; Kit Maker mock =
decisão de produto).

https://claude.ai/code/session_01HjiGVkF3Df9GiFjDbfxDYn
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

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

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 24, 2026 9:07pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

Warning

Review limit reached

@adm01-debug, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 5 reviews of capacity. Refill in 27 minutes and 40 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 62f456cf-769e-4153-b41b-047236cc12cd

📥 Commits

Reviewing files that changed from the base of the PR and between 9e1148e and 5303358.

📒 Files selected for processing (2)
  • audit/AUDITORIA_FRONTEND_MCP_2026-05-24.md
  • supabase/migrations/20260524210000_harden_anon_grants_and_password_reset_rate_limit.sql
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/epic-faraday-GQILK

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

@supabase
Copy link
Copy Markdown

supabase Bot commented May 24, 2026

Updates to Preview Branch (claude/epic-faraday-GQILK) ↗︎

Deployments Status Updated
Database Sun, 24 May 2026 21:07:05 UTC
Services Sun, 24 May 2026 21:07:05 UTC
APIs Sun, 24 May 2026 21:07:05 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 Sun, 24 May 2026 21:07:11 UTC
Migrations Sun, 24 May 2026 21:09:38 UTC
Seeding ⏸️ Sun, 24 May 2026 21:06:59 UTC
Edge Functions ⏸️ Sun, 24 May 2026 21:06:59 UTC

❌ Branch Error • Sun, 24 May 2026 21:09:38 UTC

ERROR: function public.can_view_all_sales() does not exist (SQLSTATE 42883)
At statement: 7
ALTER FUNCTION public.can_view_all_sales()                                                         SECURITY INVOKER

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

@adm01-debug adm01-debug marked this pull request as ready for review May 24, 2026 21:18
Copilot AI review requested due to automatic review settings May 24, 2026 21:18
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@adm01-debug adm01-debug merged commit d5070ea into main May 24, 2026
27 of 33 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Hardens Supabase security posture by removing public API access to internal SECURITY DEFINER functions and adding rate limiting to password reset requests, with accompanying audit documentation updates.

Changes:

  • Revokes EXECUTE from anon/authenticated on two internal public functions.
  • Adds a SECURITY DEFINER trigger function to rate-limit inserts into password_reset_requests.
  • Updates the audit report with a “Rodada 2” validation summary and the applied fixes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
supabase/migrations/20260524210000_harden_anon_grants_and_password_reset_rate_limit.sql Revokes risky function execution grants and introduces a per-email password reset insert rate limit via trigger.
audit/AUDITORIA_FRONTEND_MCP_2026-05-24.md Documents the second audit pass, validated RLS posture, and the migration applied.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +46
SELECT count(*) INTO recent_count
FROM public.password_reset_requests
WHERE lower(email) = lower(NEW.email)
AND requested_at > now() - make_interval(mins => window_minutes);

IF recent_count >= max_requests THEN
RAISE EXCEPTION 'Muitas solicitações de redefinição de senha. Tente novamente mais tarde.'
USING ERRCODE = 'check_violation';
END IF;
Comment on lines +38 to +41
SELECT count(*) INTO recent_count
FROM public.password_reset_requests
WHERE lower(email) = lower(NEW.email)
AND requested_at > now() - make_interval(mins => window_minutes);
AND requested_at > now() - make_interval(mins => window_minutes);

IF recent_count >= max_requests THEN
RAISE EXCEPTION 'Muitas solicitações de redefinição de senha. Tente novamente mais tarde.'
Comment on lines +121 to +126
| Métrica | Valor |
|---|---|
| Tabelas `public` com **RLS desabilitada** | **0** |
| Tabelas `public` com RLS habilitada | 280 |
| Políticas para os papéis `anon`/`public` | 309 |
| Dessas, com expressão **irrestrita** (`USING/CHECK = true`) | **18** |
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.

3 participants