You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A issue #6 e o PR #12 endurecem claim-leader para impedir o sequestro de liderança de salas. Hoje (produção) qualquer POST claim-leader toma a liderança de qualquer sala pública instantaneamente, sem autorização — um terceiro não participante vira líder e abusa de start/settings/reset.
O PR #12 mitiga usando estagnação da sala: só aceita a tomada quando updated_at está velho > LEADER_GRACE_MS (15s). Passou pelo quórum adversarial da frota com 2 APROVA + 1 VETO real.
O nó (as 3 lentes concordam no fato)
Não existe sinal de presença no servidor — a presença vive só no Realtime (cliente). O gate usa updated_at, mas o trigger rooms_touch só o atualiza em ações de escrita do líder (settings/start/reset), não em presença nem digitação. Logo:
Líder parada no lobby (coordenando por voz, cenário comum) → após 15s a sala "estagna" mesmo com a líder presente e ativa → sequestrável.
Durante a corrida (racing) → updated_at só é tocado no start; a digitação é broadcast puro, sem writes → após 15s a sala estagna e um POST forjado pode tomar a liderança e chamar reset/finish.
O PR melhora estritamente o status quo (de "sequestro instantâneo sempre" para "só após 15s de inatividade de escrita"), mas não fecha o caso mais comum de #6.
Heartbeat de presença server-side. Nova coluna leader_seen_at + o cliente-líder faz um ping periódico (ex.: a cada 5s) que toca a coluna; o gate passa a usar leader_seen_at. Fecha o furo de verdade, mas exige migração aditiva + writes periódicos (custo de banco; atenção à área sagrada de latência durante a corrida — o ping deve ficar fora do laço de input).
Ler presença do Realtime no servidor. O servidor consulta o canal de presença Supabase para confirmar se o líder ainda está conectado antes de rejeitar/aceitar o claim. Mais fiel, porém acopla a rota ao Realtime e tem complexidade/latência própria.
Reduzir a janela de graça (ex.: 15s → 5s) como paliativo sobre a opção 1 — diminui a superfície sem migração, ao custo de eleições legítimas mais agressivas.
Recomendação da frota
Opção 1 agora (é um ganho de segurança real e reversível) + abrir issue de evolução para a opção 2 (heartbeat) como o fix definitivo — se o dono aceitar o tradeoff de 15s no interim. Se o tradeoff não for aceitável em produção, ir direto para a opção 2. Decisão de arquitetura/custo é do dono; a frota não mergeia núcleo.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Contexto
A issue #6 e o PR #12 endurecem
claim-leaderpara impedir o sequestro de liderança de salas. Hoje (produção) qualquer POSTclaim-leadertoma a liderança de qualquer sala pública instantaneamente, sem autorização — um terceiro não participante vira líder e abusa destart/settings/reset.O PR #12 mitiga usando estagnação da sala: só aceita a tomada quando
updated_atestá velho >LEADER_GRACE_MS(15s). Passou pelo quórum adversarial da frota com 2 APROVA + 1 VETO real.O nó (as 3 lentes concordam no fato)
Não existe sinal de presença no servidor — a presença vive só no Realtime (cliente). O gate usa
updated_at, mas o triggerrooms_touchsó o atualiza em ações de escrita do líder (settings/start/reset), não em presença nem digitação. Logo:racing) →updated_atsó é tocado nostart; a digitação é broadcast puro, sem writes → após 15s a sala estagna e um POST forjado pode tomar a liderança e chamarreset/finish.O PR melhora estritamente o status quo (de "sequestro instantâneo sempre" para "só após 15s de inatividade de escrita"), mas não fecha o caso mais comum de #6.
Opções
leader_seen_at+ o cliente-líder faz um ping periódico (ex.: a cada 5s) que toca a coluna; o gate passa a usarleader_seen_at. Fecha o furo de verdade, mas exige migração aditiva + writes periódicos (custo de banco; atenção à área sagrada de latência durante a corrida — o ping deve ficar fora do laço de input).Recomendação da frota
Opção 1 agora (é um ganho de segurança real e reversível) + abrir issue de evolução para a opção 2 (heartbeat) como o fix definitivo — se o dono aceitar o tradeoff de 15s no interim. Se o tradeoff não for aceitável em produção, ir direto para a opção 2. Decisão de arquitetura/custo é do dono; a frota não mergeia núcleo.
PR: #12 · Issue: #6
All reactions