Anti-trapaça de jogo
O jogo que um visitante joga por alguns segundos é a parte que você vê. Por baixo dele está o sistema de anti-trapaça que faz o jogo valer como prova de um humano. A Caputchin pega emprestado o manual que jogos multiplayer competitivos usam contra trapaceiros: o servidor é autoritativo sobre cada rodada, o jogo roda em uma sandbox trancada, e o resultado é rederivado reexecutando as entradas do jogador. O jogo pode ser jogado, não falsificado.
Este é o terceiro portão de verificação, empilhado com proof of work e instrumentação. Ele é configurado por chave na página de Segurança.
O ciclo de vida
Uma rodada passa por três fases: montada no servidor antes do jogo, rodada em sandbox no navegador durante o jogo, e reverificada no servidor depois do jogo.
Antes da rodada: montagem autoritativa no servidor
Tudo o que decide o que a rodada é acontece no servidor, nunca no navegador. Este é o princípio de "nunca confie no cliente" do anti-trapaça multiplayer: o cliente envia intenção, o servidor decide a realidade.
- Um tíquete assinado, de uso único acuna a rodada. Ele é de vida curta e só pode ser gasto uma vez. Um tíquete capturado não pode ser reexecutado em uma segunda aprovação.
- O jogo e sua semente aleatória são escolhidos no servidor e carregados no tíquete. O navegador não pode escolher um jogo mais fácil ou uma semente mais amigável, porque ele nunca faz essa escolha.
- Um jogo diferente do pool elegível a cada vez. Um solucionador nunca sabe qual jogo vai enfrentar, então não pode pré-treinar em um único alvo estático. Operadores podem estreitar o rodízio, mas o servidor sempre escolhe do conjunto permitido. O pool em si só contém jogos que passaram em uma checagem de conformidade no momento da indexação. Veja construir um jogo de marketplace.
Durante a rodada: um jogo em sandbox
O jogo roda no navegador do visitante, mas dentro de uma fronteira que protege tanto o site do visitante quanto a integridade da rodada.
O <caputchin-game> monta cada jogo em um iframe isolado sem acesso de mesma origem, então o jogo tem uma origem opaca e não consegue alcançar os cookies, o armazenamento, o DOM ou a rede de mesma origem da página anfitriã. Sua content-security-policy inline fixa o script exatamente no bundle do jogo e bloqueia chamadas de rede de saída, e o bundle é conferido contra um hash conhecido antes de rodar (um descompasso falha de forma fechada). A própria política de segurança da página anfitriã fica intocada. O formato exato da sandbox e da política está documentado em como a Caputchin coloca os jogos em sandbox.
A conclusão: o jogo é não-confiável-por-padrão e contido. Ele não consegue exfiltrar nada, e não consegue adulterar a página em que está embutido.
Depois da rodada: replay determinístico
Quando o visitante termina, o navegador envia o trace de entradas registrado. O servidor não acredita na palavra do navegador sobre o resultado. Ele reexecuta o trace.
- A rodada é ressimulada no servidor sob a mesma semente derivada no servidor, em um isolate selado sem acesso à rede e com um orçamento de tempo rígido. Esta é a mesma propriedade em que o lockstep determinístico se apoia nos jogos de estratégia: semente idêntica mais entradas idênticas reproduzem jogo idêntico. Um trace que não resolveu de fato o jogo não reproduz um resultado de aprovação.
- Aprova ou reprova é tirado desse replay, nunca de um número que o navegador reportou. Um cliente não pode alegar uma pontuação que não ganhou.
- Um token assinado é emitido só se o replay confirmar o jogo. Esse token é ele mesmo de uso único quando seu backend depois o confirma no momento da verificação.
O que a Caputchin não faz
A maioria dos CAPTCHAs de jogo e interativos se apoia em sinais comportamentais: entropia de trajeto de mouse, timing de toque, telemetria de aparelho alimentada a um classificador que adivinha bot-contra-humano. A Caputchin deliberadamente não faz isso. Ela não coleta nenhum perfil comportamental do jogador. Em vez de adivinhar como as entradas foram produzidas, ela rederiva se elas de fato resolvem o jogo a partir dos primeiros princípios. Isto é tanto uma postura de privacidade quanto de segurança: não há modelo comportamental para enganar, só física para reproduzir.
Um limite honesto
O portão é tão forte quanto o jogo. O maquinário de anti-trapaça prova que uma rodada foi genuinamente jogada e não falsificada, mas não consegue tornar um jogo fácil em difícil. Um jogo trivial (um tabuleiro estático, a jogada vencedora legível no DOM, "clique no ponto vermelho para passar") é barato para um script resolver, e o replay determinístico vai fielmente confirmar que essas entradas roteirizadas vencem, porque elas vencem. A resistência a bots vem do próprio jogo ser difícil de resolver programaticamente: reações rápidas, sensoriais, numa fração de segundo, sem solução parada no DOM. A camada de anti-trapaça garante que o jogo foi real; o design do jogo decide se o jogo real foi difícil de automatizar. Escolha e construa jogos com isso em mente, veja construir um jogo de marketplace.
Aprova ou reprova é decidido pela própria lógica de cada jogo; o servidor reexecuta fielmente essa lógica mas não questiona o que um dado jogo considera uma vitória. O anti-trapaça de jogo é mais forte composto com proof of work, instrumentação e o resto das configurações de segurança de uma chave.