Javascript anti-fraude para navegador / jogo HTML5

35

Estou pensando em me aventurar em criar um rpg de ação para um jogador em js / html5 e gostaria de evitar trapacear. Não preciso de 100% de proteção, já que não será um jogo multiplayer, mas quero um certo nível de proteção.

Então, quais estratégias você sugere além da minificação e ofuscação?

Eu não me incomodaria em fazer uma verificação simples no servidor, mas não quero seguir o caminho do Diablo 3 mantendo todas as alterações no estado do jogo no servidor.

Como vai ser um tipo de rpg, tive a idéia de criar um inspetor de estatísticas que verifique mudanças bruscas em seus valores, mas não tenho certeza de quão consistente e confiável possa ser.

E quanto a variáveis ​​e escopos de funções? Trabalhar em escopos menores sempre que possível é mais seguro, mas vale a pena o esforço?

Existe alguma maneira para o javascript auto-inspecionar seu texto, como em uma soma de verificação?

Existem soluções específicas para navegadores? Eu não me incomodaria em restringi-lo ao Chrome apenas nas versões iniciais.

Billy Ninja
fonte
Onde seus dados são salvos, como eles são salvos?
dogdog
Engraçado você falar sobre o Diable 3, o "caminho do Diablo 1" era exatamente isso, confiando no cliente. Faça uma pesquisa no google se você é jovem demais para lembrar o que aconteceu por causa disso!
Valmond
Apoc, agora só tenho uma prova de conceito e não implementei nenhum tipo de persistência - mas pretendo implementar alguma persistência de banco de dados nas primeiras construções e / ou armazenamento local, para que os jogadores não possam continuar jogando de onde deixaram. Sim, Valdmond, eu joguei minha parte do Diablo naquela época. Mas não estou construindo um jogo multiplayer competitivo ou um AAA completo. Byte56, eu não estou interessado em roubar o meu código (quem iria querer essa porcaria de qualquer maneira?)
Billy Ninja
Infelizmente, você tem que ir o caminho diablo 3, se você está realmente preocupado com hacks / Cheats
Noob Game Developer

Respostas:

46

A resposta curta é que você não pode fazê-lo. Qualquer coisa que execute no lado do cliente, especialmente da fonte, pode ser modificada para derrotar suas táticas trivialmente. Se você colocar um verificador do lado do cliente para procurar alterações abruptas, um usuário poderá simplesmente desativar o verificador.

A boa notícia é que, geralmente, há muito pouca trapaça nos jogos para um jogador. A única exceção importante é para jogos que têm grandes comunidades de "altas pontuações no youtube" como o Line Rider, onde os jogadores competem entre si pelo YouTube.

Se você está buscando isso, ou é teimoso demais para aceitar que as pessoas trapaceiam no jogo ou está mantendo uma pontuação alta (que é uma forma de multiplayer), o que você deve fazer é todos os cálculos do lado do servidor . Sim, tudo o que importa. Você não pode nem repetir o lado do cliente de cálculo para tentar dar ao usuário a pontuação e, em seguida, 'verificá-la' com o servidor, porque o usuário pode simplesmente desativar a verificação e desativar qualquer sistema que garanta a verificação.

Eu gostaria que houvesse uma resposta melhor para isso, mas não existe.

Dito isto, há coisas que você pode fazer para tornar um pouco mais difícil de enganar. Eles não impedirão ninguém sério de fazer isso e liberar um kit de ferramentas para trapacear, mas isso os atrasará:

  • Minimize e ofusque seu JS, o que absolutamente tornará o código mais difícil de ler. Você pode desminificar e classificar de ofuscar, mas nunca poderá recuperar os nomes corretos de variáveis ​​e funções, nem comentários.
  • Asse em valores com um idioma diferente. Nesse caso, você pode usar PHP ou outras linguagens do lado do servidor para lidar com variáveis ​​de configuração estática. Se a distância do salto sempre deve ter 2 espaços, normalmente você definiria uma distância do salto para o objeto do jogador. Não, lide com isso com PHP para que a fonte JS termine com 2s colados em todo o código em um milhão de lugares. Isso tem o feliz efeito colateral adicional de poder acelerar seu JS também.
  • Com alguma prática, você se familiarizará com o mix e poderá até criar seu JS personalizado para cada jogador. Qual é outra maneira de evitar trapaças. Se o código de cada jogador for diferente de alguma forma, será mais difícil escrever uma trapaça que possa fazer parte de um kit de ferramentas.
  • Finalmente, você pode somar a fonte com base na identidade do jogador. Diga o endereço IP e / ou nome de usuário. Você sabe qual será a versão específica do jogador do JS, é possível criar uma soma de verificação e exigir que seja a mesma do outro lado. Fácil de desabilitar como qualquer JS do lado do cliente, mas mais uma vez torna um pouco mais difícil criar um kit de ferramentas.

Tão. Como você vê, provavelmente não vale a pena seguir esse caminho. É difícil. Requer muitas práticas de codificação realmente tolas, e ainda é relativamente fácil de derrotar. Você precisará fazer todos os cálculos do lado do servidor para evitar trapaças. Ou deixe ir e aceite que a trapaça acontecerá.

DampeS8N
fonte
O exemplo de piloto de linha é realmente bastante trivial para o servidor, permitindo que o usuário faça o upload do mapa que ele / ela desenhou e calcule a pontuação. Mas jogos como fliperamas são quase impossíveis de calcular a pontuação do lado do servidor sem muito trabalho.
orlp
@nightcracker Você está correto, no entanto, mesmo com algo como o Line Rider, se você apenas verificar após o jogo terminar, o vídeo foi feito e os YouTubes já foram enganados. Você deve fazer o upload do mapa quando o usuário clicar em play, calcular o caminho que é trivial e enviá-lo de volta. O jogo não deve ser capaz de calcular o caminho. (Se nós estamos falando sobre tornando-se enganar prova, que esse jogo não é É apenas o suficiente simples que batota é óbvio para seus fãs..)
DampeS8N
14

Eu já respondi uma pergunta como essa aqui e lamento dizer, mas:

Eu não me incomodaria em fazer uma verificação simples no servidor, mas não quero seguir o caminho do Diablo 3 mantendo todas as alterações no estado do jogo no servidor.

É a pior coisa que você poderia dizer aqui. Se você quiser fazer um mecanismo "anti-fraude", precisará fazer isso. Você pode adicionar o que quiser do lado do cliente, para facilitar o trabalho do servidor, mas nunca deve confiar no cliente. Toda a lógica que você possui deve ser pelo menos do lado do servidor. Você pode reproduzi-lo do lado do cliente, se quiser, mas nenhuma solução somente do lado do cliente fará isso.

E, a propósito, se você quiser encontrar a fraqueza do seu programa, não ofusque-o, deixe que as pessoas vejam seu código e digam "aqui, você tem um problema".

Isso é bom para você, para seu código, para seus usuários e para a comunidade.

dievardump
fonte
3
+1 para autoridade do servidor, apenas não funcionará se você tentar confiar no cliente ...
Valmond
É perigoso reproduzir coisas do lado do cliente. Tenha cuidado, mesmo porque, se tudo for replicado no lado do cliente, o usuário poderá trapacear desconectando as verificações do servidor. Eles podem jogar, gravar um vídeo e se tornar uma estrela do YouTube. Isso é aplicável apenas a jogos para um jogador, que será esse jogo.
DampeS8N
Quando falo sobre o lado do cliente, é para "cálculo de movimentos", "colisões" etc ... Isso pode ser feito nos dois lados, mesmo para um jogo multiplayer. Os cálculos do lado do servidor sempre devem ser considerados prioritários, mas isso pode ajudar quando há latência do servidor para tê-lo também do lado do cliente. Mas para tudo o que é lógica de "cheat cheat", concordo que tudo deve ser do lado do servidor.
dievardump
Sim, entendi. Mas estou fazendo o projeto como um hobby no pouco tempo livre que tenho. Fazer esse tipo de verificação de servidor aumentaria bastante a complexidade do projeto, tornando-o inviável. Bem, continuarei com o projeto sabendo disso, e se ele começar a ficar maior e mais sério do que eu poderia ter algum controle sério no lado do servidor, provavelmente com o Node.js.
Billy Ninja
esta é a resposta mais apropriada para OP
Noob Game Developer
3

Bem, um bom lugar para começar é usar a função Object.freeze (que ativará a proteção contra o patch de objetos).

Isso "impede que novas propriedades sejam adicionadas", "impede que as propriedades existentes sejam removidas", "impede que as propriedades existentes ou sua enumerabilidade, configurabilidade ou gravabilidade sejam alteradas"; quaisquer alterações no estado interno devem ser feitas por meio de acessadores. O exemplo a seguir funciona no chrome (deve funcionar no firefox, embora eu não conheça o IE ...):

var b = {}
// Fill your object with whatever you want
b.a = "ewq"
// Freeze all changes
Object.freeze(b)
// Try to put new value. This wont throw any error, put wont work either, 
// as we shall see ...
b.b = "qwe"

// Values 
console.log(b.a); // outputs "eqw"
console.log(b.b); // outputs  undefined
fábula
fonte
5
Mesmo isso apenas atrasa um trapaceiro determinado. Se nada mais puder roubar a fonte, hospede-a em sua própria máquina e remova o código de congelamento e use o arquivo hosts para induzir o navegador a pensar que a nova página é antiga, reconectando-a ao servidor.
DampeS8N
@ DampeS8N Sim, acho que você está certo.
fableal 20/09/12
Como eu disse no OP, eu só quero algum nível de proteção.
Billy Ninja
Isso não vai ajudar em nada! O usuário pode apenas definir um ponto de interrupção do depurador na primeira função JS que é executada e entra Object.freeze = function(o) {};no console JS.
Philipp
2

infelizmente, você deve seguir o caminho do diablo 3, se estiver realmente preocupado com hacks / cheats. se não estiver, as verificações básicas que você deve fazer ou é altamente recomendável que você faça.

  • comprar cheques - Se estou comprando algo, devo ter ouro suficiente
  • cheques de venda - Se estou vendendo algo, preciso ter esse item nas verificações de troca de estoque - o mesmo que vender armas
  • equipar cheques - Se estou equipando uma arma, eu a possuo?
  • verificações de dano - Se estou atacando algo (inimigo), não posso atingir mais do que o dano máximo que minha arma poderia (aqui você não deve esperar que o cliente diga qual arma ele usou porque deveria ter sido mantida anteriormente)
  • verificações de elaboração - Se eu criei algo, tenho todos os ingredientes / componentes necessários?

... e assim por diante

1 ponto é um pouco complicado é a posição do herói, já que você não está muito preocupado com isso, pode deixá-lo, mas é melhor você fazer isso também com uma verificação mínima como a abaixo

  • Estou no lugar1 @ T1, estou no lugar2 T2, qual é o tempo mínimo necessário para viajar de um lugar1 para o lugar2 e corresponde ao meu T2 - T1. Você pode mapear isso de pequeno a grande, dependendo do tamanho do mapa. Você deve ter uma lista de pelo menos áreas principais como, NPC - chefe, NPC - área de desova inimiga (não necessariamente a localização exata)

Espero que isso ajude, parece difícil, mas você precisa aprender a criar jogos de trabalho reais

Noob Game Developer
fonte
Ótima resposta! Eu estava escrevendo uma pergunta sobre como implementar a verificação do servidor, apenas para medir aproximadamente o quão difícil é implementar a verificação do servidor. Veja bem, eu não quero perder dezenas de horas implementando um backbone do tipo MMO e, no final do dia, ainda é fácil enganar apenas substituindo algum parâmetro de solicitação do cliente ou algo assim. Ou simplesmente exagere no que deveria ser um jogo simplesmente divertido - desperdice a segurança em vez de fornecer recursos mais interessantes ou aperfeiçoar as coisas.
Billy Ninja
1

Basicamente não é possível. Seria tão fácil contornar qualquer coisa que você colocar no lugar para evitar trapacear.

O problema é que, com qualquer software que você distribuir, as pessoas podem modificá-lo facilmente na memória.

Além disso, se eles querem trapacear, deixe-os. Eles estão apenas arruinando o jogo por si mesmos. Não há nenhum uso prático real para trapacear nessa situação, você apenas destruiria a jogabilidade por si mesmo.

tsturzl
fonte
1

Tive uma idéia para uma medida que você pode tomar para evitar / reduzir trapaças (além de outras respostas). Você pode configurá-lo para que o cliente não receba todo o código-fonte de uma só vez, e que toda vez que o cliente queira, por exemplo, comprar um novo item na loja, o cliente precisará enviar determinadas informações para o servidor e só recebe todas as informações do que eles estão comprando se todas as informações corresponderem ao que deveria. Caso contrário, o servidor coloca na lista negra seu IP ou algo assim.

Você pode usar isso em conjunto com o que o Dampes8n disse sobre o uso de diferentes versões de origem, que, se você puder descobrir uma maneira de gerar várias versões diferentes, para que cada usuário esteja executando uma versão de origem totalmente diferente a cada vez, isso falhará no verifique nas listas negras também a versão de origem, para que nunca mais forneça as informações corretas do item para essa versão de origem.

A principal razão pela qual isso seria eficaz é que, se um hacker não acertar o hack da primeira vez, isso tornaria muito mais difícil a modificação do hack, porque toda vez que o hack não funciona perfeitamente, eles precisam altere seu IP e escreva o hack novamente para a nova versão de origem.

AJMansfield
fonte
Eu teria cuidado. A última coisa que você quer fazer é banir acidentalmente um cliente pagador.
John McDonald
@JohnMcDonald True, isso. Talvez apenas matando essa versão de origem. Dessa forma, se eles acidentalmente acionarem a armadilha, eles apenas terão que atualizar o navegador, enquanto ainda fazem os hackers recodificarem todos os seus hacks.
AJMansfield
0

Sim, não pode totalmente ser feito. Sempre verifique no servidor. Qualquer coisa que tenha impacto no jogo deve exigir autorização do servidor.

Essa é a extensão em que repetirei outras respostas.

No entanto, podemos fazer muito mais para evitar fraudes do que apenas checar o servidor. Bem, talvez tenhamos que adicionar algumas verificações especiais ao servidor.No entanto, esteja ciente de que as verificações do lado do cliente não são inúteis, pois economizam largura de banda e trabalho do servidor quando os trapaceiros não estão envolvidos.

Com isso dito:

  • Atenuar clientes brutos: atenda por HTTPS, use o compartilhamento de recursos de origem cruzada (CORS), permita apenas a mesma origem, use a integridade do sub-recurso. Sugiro implementar um trabalhador de serviço para aplicá-lo em todas as solicitações, o que também significa que o jogo não funcionará simplesmente movendo-o para HTTP (porque sem HTTPS não há trabalhador de serviço, o trabalhador de servidor está fazendo parte do cliente O CORS e o servidor esperam o CORS) e, se eles servirem por HTTPS, não funcionará porque o servidor rejeitará a outra origem.
  • Mitigar scripts: use autenticação e exija um token para executar qualquer ação. Cada ciclo de atualização que o servidor deve fornecer ao cliente um novo token, e o token é consumido fazendo o que faz ... fazer qualquer coisa requer um token válido, o token está sempre mudando e, portanto, não é viável de adivinhar, e se o cliente envia o mesmo token duas vezes ou envia um token errado, o servidor sabe que algo está acontecendo. Para proteção extra: crie um código de autenticação de mensagem (MAC) do token com uma chave secreta e adicione-o ao cookie. A modificação do cookie interromperá a sessão (e eles precisam adivinhar a chave) e a modificação do token fará com que a verificação do MAC falhe.
  • Atenuar modificações no código: Além da integridade do sub-recurso (que navegadores modernos também verificarão em tempo de execução), mantenha suas variáveis ​​sob um escopo limitado (usando let, funções anônimas auto-executáveis ​​e módulos javascript). Além disso, não confie no DOM (o DOM é apenas para E / S, não para armazenamento, se você precisar anexar atributos, agrupe seus objetos DOM e inclua-os nos wrappers). Dessa forma, o que você estiver usando no console não poderá alcançar a lógica do jogo (a menos que você explore alguma vulnerabilidade do navegador). Você também pode considerar o uso de técnicas para detectar ferramentas de desenvolvedor (elas são específicas por navegador e podem não funcionar em todos os casos ou parar de funcionar no futuro ... portanto, esta é uma corrida armamentista).
  • Algo está acontecendo? A sessão terminou? Retroceda o jogador da partida atual, solicite o login novamente. Considere um captcha ... que também tenha o benefício de informar ao usuário que "sabemos que algo raro está acontecendo" (não foi uma falha aleatória do servidor) e sim, isso é uma forma de atenuação. Ah, e não foge para registrá-los. Você precisa verificar por que eles aconteceram, tanto para evitar postives falsos quanto para responder a tíquetes de suporte.

Sim, isso tudo são mitigações. Ainda podemos ter um navegador personalizado que não verifica a integridade e permite que você alcance e mexa com variáveis ​​nos escopos locais ... então o código do jogo enviará os dados modificados com o token certo, e é aí que as verificações do servidor são realizadas Toque.

Theraot
fonte