Javascript anti-cheat per browser / gioco HTML5


35

Ho intenzione di avventurarmi a fare un gioco di ruolo in single player in js / html5, e mi piacerebbe evitare di imbrogliare. Non ho bisogno di protezione al 100%, dal momento che non sarà un gioco multiplayer, ma voglio un certo livello di protezione.

Quindi quali strategie suggerisci oltre a minimizzare e offuscare?

Non mi preoccuperei di effettuare alcuni semplici controlli lato server, ma non voglio seguire il percorso di Diablo 3 mantenendo tutte le modifiche allo stato del gioco sul lato server.

Dal momento che sarà una specie di rpg mi è venuta l'idea di creare un ispettore statistico che controlli bruschi cambiamenti nei loro valori, ma non sono sicuro di quanto possa essere coerente e affidabile.

Che dire di variabili e funzioni escopes? Lavorare su scale più piccole ogni volta che è possibile è più sicuro, ma ne vale la pena?

Esiste comunque un javascript per autoispezionare il suo testo, come in un checksum?

Esistono soluzioni specifiche per browser? Non mi preoccuperei di trattenerlo per Chrome solo nelle prime build.


Dove vengono salvati i tuoi dati, come vengono salvati i tuoi dati?
DogDog,

Divertente che parli di Diable 3, "Diablo 1 way" era esattamente questo, fidandosi del cliente. Fai una ricerca su Google se sei troppo giovane per ricordare cosa è successo a causa di quello!
Valmond,


Apoc, in questo momento ho solo una prova del concetto e non ho implementato alcun tipo di persistenza, ma ho intenzione di implementare un po 'di persistenza DB nelle prime build e / o archiviazione locale in modo che i giocatori non possano continuare a giocare da dove hanno lasciato. Sì, Valdmond ho giocato la mia parte di Diablo allora. Ma non sto costruendo un gioco multiplayer competitivo o un AAA completamente segnalato. Byte56, non mi preoccupo di rubare il mio codice (chi vorrebbe comunque quella schifezza?)
Billy Ninja,

sfortunatamente, devi seguire il percorso di diablo 3, se sei davvero preoccupato per hack / cheat
Noob Game Developer,

Risposte:


46

La risposta breve è che non puoi farlo. Tutto ciò che gestisce il lato client, specialmente dalla fonte, può essere modificato per sconfiggere banalmente le tue tattiche. Se si imposta un controllo lato client per cercare modifiche improvvise, un utente può semplicemente disabilitare il controllo.

La buona notizia è che, in generale, c'è molto poco inganno nei giochi per giocatore singolo. L'unica eccezione importante è per i giochi che hanno grandi community "youtube highscore" come Line Rider, in cui i giocatori competono tra loro su YouTube.

Se stai mirando a questo, o sei troppo testardo per accettare che le persone possano imbrogliare nel gioco, o stai mantenendo tu stesso i punteggi più alti (che è una forma di multiplayer), allora tutto ciò che devi fare è tutti i calcoli sul lato server . Sì, tutto ciò che conta. Non è nemmeno possibile ripetere il lato client di calcolo per provare a dare all'utente il punteggio e quindi 'verificarlo' con il server perché l'utente può semplicemente disabilitare il controllo e disabilitare qualsiasi sistema che garantisca che ci siano controlli.

Vorrei che ci fosse una risposta migliore a questo, ma non lo è.

Detto questo, ci sono cose che puoi fare per rendere un po 'più difficile imbrogliare. Non impediranno a nessuno serio di farlo e di rilasciare un toolkit per imbrogliare, ma li rallenterà:

  • Minimizza e offusca il tuo JS, il che renderà il codice più difficile da leggere. È possibile de-minificare e smascherare una sorta di de-offuscamento, ma non è mai possibile recuperare la variabile corretta, i nomi delle funzioni e i commenti.
  • Inserisci valori con una lingua diversa. In questo caso è possibile utilizzare PHP o altre lingue lato server per gestire variabili di configurazione statiche. Se si suppone che la distanza di salto sia sempre di 2 spazi, normalmente si definirebbe una distanza di salto per l'oggetto giocatore. No, gestiscilo con PHP in modo che la sorgente JS finisca con 2s intonacati in tutto il codice in un milione di posti. Questo ha il felice effetto collaterale aggiuntivo di poter accelerare anche il tuo JS.
  • Con un po 'di pratica, diventerai abile con il mix e potrai persino costruire il tuo JS su misura per ogni giocatore. Questo è un altro modo per prevenire i tradimenti. Se il codice di ogni giocatore è diverso in qualche modo, è più difficile scrivere un trucco che può far parte di un toolkit.
  • Infine, puoi fare il checksum della fonte in base all'identità del giocatore. Pronuncia il loro indirizzo IP e / o nome utente. Sai quale sarà la versione specifica del giocatore di JS, puoi effettuare un checksum e richiedere che sia lo stesso dall'altra parte. Facile da disabilitare come qualsiasi JS lato client, ma ancora una volta rende più difficile la creazione di un toolkit.

Così. Come vedi, probabilmente non vale la pena percorrere questa strada. È difficile. Richiede molte pratiche di programmazione davvero stupide ed è ancora relativamente facile da sconfiggere. Dovrai fare tutti i calcoli sul lato server per evitare imbrogli. O lascia andare, e accetta che accada succederà.


L'esempio del line rider è in realtà abbastanza banale da fare sul lato server, consentendo all'utente di caricare la mappa che ha disegnato e calcolare il punteggio. Ma giochi come i portici sono quasi impossibili da calcolare il punteggio sul lato server senza un lungo lavoro.
orlp,

@nightcracker Hai ragione, comunque anche con qualcosa come Line Rider, se controlli solo dopo che il gioco è finito, il video è stato realizzato e gli YouTub sono già stati ingannati. Dovresti caricare la mappa quando l'utente va a giocare, calcolare il percorso che è banale e quindi rispedirlo. Il gioco non dovrebbe essere in grado di calcolare il percorso. (Se stiamo parlando di renderlo a prova di imbrogli, cosa che non è quel gioco. È abbastanza semplice che imbrogliare sia ovvio per i suoi fan.)
DampeS8N

14

Ho già risposto a una domanda del genere qui , e mi dispiace dirlo ma:

Non mi preoccuperei di effettuare alcuni semplici controlli lato server, ma non voglio seguire il percorso di Diablo 3 mantenendo tutte le modifiche allo stato del gioco sul lato server.

È la cosa più brutta che potresti dire qui. Se vuoi fare un motore "anti-cheat", dovrai farlo. Puoi aggiungere tutto ciò che desideri sul lato client, per facilitare il lavoro sul lato server, ma non devi mai fidarti del client. Tutta la logica che hai deve essere almeno sul lato server. Puoi riprodurlo sul lato client se vuoi, ma nessuna soluzione sul lato client lo farà.

E a proposito, se vuoi trovare la debolezza del tuo programma, non offuscarlo, lascia che le persone vedano il tuo codice e ti diano "qui, hai un problema".

Questo è un bene per te, per il tuo codice, per i tuoi utenti e per la community.


3
+1 per l'autorità del server, non funziona se si tenta di fidarsi del client ...
Valmond,

È pericoloso riprodurre le cose sul lato client. Fai attenzione anche a questo, perché se tutto viene replicato sul lato client, l'utente può imbrogliare disconnettendo i controlli con il server. Possono quindi giocare, registrare un video e diventare una star di YouTube. Questo è applicabile solo ai giochi per giocatore singolo, come sarà questo gioco.
DampeS8N,

Quando parlo di lato client, è per "calcolo dei movimenti", "collisioni" ecc ... Questo può essere fatto su entrambi i lati anche per una partita multiplayer. I calcoli sul lato server devono sempre essere considerati prioritari, ma ciò può essere d'aiuto in caso di latenza del server per averla anche sul lato client. Ma per tutto ciò che è la logica "check cheat", sono d'accordo che tutto dovrebbe essere lato server.
dievardump,

Sì, l'ho capito. Ma sto facendo il progetto come un hobby nel poco tempo libero che ho. Fare quel tipo di controllo del server significherebbe molto la complessità del progetto, rendendolo non praticabile. Bene, continuerò a muovermi con il progetto sapendolo, e se inizia a diventare più grande e serio di quanto potrei trovare un serio controllo lato server, probabilmente con Node.js.
Billy Ninja,

questa è la risposta più appropriata a OP
Noob Game Developer il

3

Bene, un buon punto di partenza è usare la funzione Object.freeze (che abiliterà la protezione contro il patching degli oggetti).

Questo "impedisce l'aggiunta di nuove proprietà", "impedisce la rimozione di proprietà esistenti", "impedisce di modificare le proprietà esistenti o la loro enumerabilità, configurabilità o scrivibilità"; qualsiasi modifica allo stato interno dovrebbe essere effettuata tramite gli accessori. Il seguente esempio funziona su Chrome (dovrebbe funzionare su Firefox, non so di IE però ...):

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

5
Anche questo rallenterà solo un imbroglione determinato. Se non altro, può rubare la fonte, ospitarla sul proprio computer e rimuovere il codice di blocco, quindi utilizzare il file hosts per indurre il suo browser a pensare che la nuova pagina sia quella vecchia, ricollegandola al server.
DampeS8N,

@ DampeS8N Sì, immagino tu abbia ragione.
fableal,

Come ho detto nel PO, voglio solo un certo livello di protezione.
Billy Ninja,

Questo non aiuta affatto! L'utente può semplicemente impostare un punto di interruzione del debugger nella prima funzione JS che viene eseguito ed entrare Object.freeze = function(o) {};nella console JS.
Philipp,

2

sfortunatamente, devi seguire il percorso di diablo 3, se sei davvero preoccupato per hack / cheat. se non lo sei, allora controlli di base che devi fare o è fortemente consigliato di fare.

  • comprare assegni - Se sto acquistando qualcosa, dovrei avere abbastanza oro
  • sellchecks - Se sto vendendo qualcosa, devo avere quell'oggetto nei miei controlli di inventario - lo stesso che vendere l'arma
  • equipaggia i controlli - Se sto equipaggiando un'arma, la possiedo / la possiedo?
  • controllo danni - Se sto attaccando qualcosa (nemico), non posso colpire più del massimo danno che la mia arma potrebbe (qui non dovresti aspettarti che il cliente dica quale arma ha usato perché avrebbe dovuto persistere prima)
  • controlli di fabbricazione - Se ho creato qualcosa, ho tutti gli ingredienti / componenti necessari?

... e così via

1 punto è un po 'complicato è la posizione dell'eroe, poiché non sei molto preoccupato per questo puoi lasciarlo, ma è meglio farlo anche con un controllo minimo come quello sotto

  • Sono in place1 @ T1, sono in place2 T2, qual è il tempo minimo necessario per viaggiare da place1 a place2 e corrisponde al mio T2 - T1. Puoi avere una mappatura di questo da piccola a grande a seconda della dimensione della mappa. Dovresti avere un elenco di almeno le principali aree come, NPC - boss, NPC - area di spawn nemica (posizione non necessariamente esatta)

Spero che questo aiuti, sembra difficile ma devi imparare a creare veri e propri giochi di lavoro


Bella risposta! Stavo scrivendo una domanda su come implementare il controllo del server, solo per misurare approssimativamente quanto sia difficile implementare il controllo del server. Vedete, non voglio sprecare decine di ore nell'implementazione di una spina dorsale simile a un MMO e alla fine della giornata è ancora facilmente acquistabile sostituendo alcuni parametri di richiesta del client o qualcosa del genere. O semplicemente esagerare con quello che doveva essere un gioco semplicemente divertente: sprecare sforzo per la sicurezza invece di offrire funzionalità più interessanti o perfezionare le cose.
Billy Ninja,

1

Fondamentalmente non è possibile. Sarebbe così facile aggirare tutto ciò che è stato messo in atto per evitare imbrogli.

Il fatto è che con qualsiasi software distribuito le persone possono modificarlo facilmente in memoria.

Inoltre se vogliono imbrogliare, lasciateli. Stanno solo rovinando il gioco da soli. Non c'è un vero uso pratico per imbrogliare in questa situazione, potresti semplicemente distruggere il gameplay per te stesso.


1

Ho avuto un'idea per una misura che potresti prendere per prevenire / ridurre i tradimenti (oltre ad altre risposte). Potresti averlo impostato in modo che al cliente non venga fornito tutto il codice sorgente in una volta, piuttosto che ogni volta che il cliente vuole, diciamo, acquistare un nuovo articolo nel negozio, che il cliente dovrebbe inviare determinate informazioni a il server e riceve tutte le informazioni per qualunque cosa stiano acquistando se tutte le informazioni corrispondono a ciò che dovrebbero. In caso contrario, il server inserisce nella blacklist il proprio IP o qualcosa del genere.

Potresti usarlo insieme a ciò che Dampes8n ha detto sull'utilizzo di diverse versioni di origine, che se riesci a trovare un modo per generare molte versioni diverse, in modo che ogni utente esegua ogni volta una versione di origine completamente diversa, che controlla anche nella blacklist quella versione di origine, che non fornirà mai più le informazioni corrette sull'elemento per quella versione di origine.

Il motivo principale per cui questo sarebbe efficace è che se un hacker non riesce a correggere l'hack per la prima volta, ciò renderebbe molto più difficile per loro modificare l'hack, perché ogni volta che l'hack non funziona perfettamente, devono cambia il loro IP e riscrive l'hack per la nuova versione di origine.


Starei attento. L'ultima cosa che vuoi fare è vietare accidentalmente un cliente pagante.
John McDonald,

@JohnMcDonald Vero, quello. Forse sto solo uccidendo quella versione sorgente. In questo modo, se attivano accidentalmente la trappola, devono solo aggiornare il browser, facendo comunque in modo che gli hacker ricodifichino tutti i loro hack.
AJMansfield,

0

Sì, non può essere fatto completamente . Controlla sempre il server. Tutto ciò che ha un impatto sul gioco dovrebbe richiedere l'autorizzazione dal server.

Questa è la misura in cui ripeterò altre risposte.

Tuttavia, possiamo fare molto di più verso la fine della prevenzione dei cheat piuttosto che controllare il server. Bene, potremmo dover aggiungere alcuni controlli speciali del server. Tuttavia, tieni presente che i controlli lato client non sono privi di valore, risparmiano larghezza di banda e lavoro del server quando i truffatori non sono coinvolti.

Detto questo:

  • Mitigare i client approssimativi: servire su HTTPS, utilizzare la condivisione delle risorse tra le origini (CORS), consentire solo la stessa origine, utilizzare l'integrità delle risorse secondarie. Suggerisco di implementare un lavoratore di servizio per imporlo su tutte le richieste, il che significa anche che il gioco non funzionerà semplicemente spostandolo su HTTP (perché senza HTTPS non esiste un lavoratore di servizio, il lavoratore del server sta facendo parte del client di CORS e il server si aspetta CORS), e se servono su HTTPS non funzionerà perché il server rifiuterà l'altra origine.
  • Mitigare gli script: utilizzare l'autenticazione e richiedere un token per eseguire qualsiasi azione. Ogni ciclo di aggiornamento che il server dovrebbe dare al client un nuovo token e il token viene consumato facendo qualunque cosa faccia ... fare qualsiasi cosa richiede un token valido, il token cambia sempre e quindi non è fattibile da indovinare, e se il client invia lo stesso token due volte o invia un token errato, il server sa che qualcosa è attivo. Per una protezione aggiuntiva: crea un codice di autenticazione dei messaggi (MAC) del token con una chiave segreta e aggiungilo al cookie. La modifica del cookie interromperà la sessione (e devono indovinare la chiave) e la modifica del token farà fallire il controllo MAC.
  • Riduci le modifiche al codice: a parte l'integrità delle risorse secondarie (che i browser moderni controlleranno anche in fase di esecuzione), mantieni le tue variabili in un ambito limitato (usando let, funzioni anonime auto-eseguite e moduli javascript). Inoltre, non fare affidamento sul DOM (il DOM è solo per IO, non per l'archiviazione, se è necessario collegare gli attributi avvolgere gli oggetti DOM e aggiungerli ai wrapper). In questo modo, qualunque cosa tu sia sulla console non dovrebbe essere in grado di raggiungere la logica di gioco (a meno che non sfrutti qualche vulnerabilità del browser). Potresti anche prendere in considerazione l'utilizzo di tecniche per rilevare strumenti per sviluppatori (specifici per browser e potrebbero non funzionare in tutti i casi o smettere di funzionare in futuro ... quindi, questa è una corsa agli armamenti).
  • Qualcosa è successo? La sessione si è interrotta? Calcia il giocatore dalla partita in corso, richiedi nuovamente l'accesso. Considera un captcha ... che ha anche il vantaggio di dire all'utente che "sappiamo che sta succedendo qualcosa di raro" (non è stato un errore casuale del server), e sì, questa è una forma di mitigazione. Oh, e non offuscare per registrare questi. Devi essere in grado di verificare perché sono accaduti, sia per prevenire posture false sia per rispondere ai ticket di supporto.

Sì, queste sono tutte mitigazioni. Possiamo ancora avere un browser personalizzato che non controlla l'integrità e ti consente di raggiungere e pasticciare con le variabili negli ambiti locali ... quindi il codice di gioco invierà i dati modificati con il token giusto, ed è qui che entrano in gioco i controlli del server giocare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.