it-swarm-eu.dev

Qual è il modo migliore per impedire alle persone di hackerare la tabella dei punteggi migliori basata su PHP di un gioco Flash

Sto parlando di un gioco d'azione senza limite di punteggio superiore e nessun modo per verificare il punteggio sul server ripetendo le mosse ecc.

Quello di cui ho davvero bisogno è la crittografia più potente possibile in Flash/PHP e un modo per impedire alle persone di chiamare la pagina PHP diversa dal mio file Flash. Ho provato alcuni semplici metodi in passato effettuare più chiamate per un singolo punteggio e completare una sequenza checksum/fibonacci ecc. e offuscare il file SWF con Amayeta SWF Encrypt, ma alla fine sono stati tutti hackerati.

Grazie alle risposte StackOverflow ora ho trovato alcune informazioni in più da Adobe - http://www.Adobe.com/devnet/flashplayer/articles/secure_swf_apps_12.html e https: // github .com/mikechambers/as3corelib - che penso di poter usare per la crittografia. Non sono sicuro che questo mi farà girare CheatEngine.

Devo conoscere le migliori soluzioni sia per AS2 che per AS3, se diverse.

I problemi principali sembrano essere cose come le intestazioni di TamperData e LiveHTTP, ma capisco che ci sono anche strumenti di hacking più avanzati, come CheatEngine (grazie Mark Webster)

212
Iain

Questo è un classico problema con giochi e concorsi su Internet. Il tuo codice Flash funziona con gli utenti per decidere un punteggio per un gioco. Ma gli utenti non sono affidabili e il codice Flash viene eseguito sul computer dell'utente. Sei SOL. Non c'è niente che tu possa fare per impedire a un attaccante di ottenere punteggi alti:

  • Flash è ancora più facile da decodificare di quanto si possa pensare, dal momento che i bytecode sono ben documentati e descrivono un linguaggio di alto livello (Actionscript) --- quando pubblichi un gioco Flash, pubblichi il tuo codice sorgente, sia che tu saperlo o no.

  • Gli aggressori controllano la memoria di runtime dell'interprete Flash, in modo tale che chiunque sappia utilizzare un debugger programmabile può modificare qualsiasi variabile (incluso il punteggio corrente) in qualsiasi momento o il programma stesso.

Il più semplice attacco possibile al tuo sistema è quello di eseguire il traffico HTTP per il gioco attraverso un proxy, catturare il salvataggio con punteggio più alto e riprodurlo con un punteggio più alto.

Puoi provare a bloccare questo attacco vincolando ogni salvataggio con punteggio elevato in una singola istanza del gioco, ad esempio inviando un token crittografato al client all'avvio del gioco, che potrebbe apparire come:

hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))

(È inoltre possibile utilizzare un cookie di sessione con lo stesso effetto).

Il codice di gioco fa eco a questo token al server con il salvataggio dei punteggi migliori. Ma un attaccante può ancora lanciare di nuovo il gioco, ottenere un gettone e quindi incollarlo immediatamente in un salvataggio di punteggio elevato rigiocato.

Quindi, successivamente, non solo si alimenta un token o un cookie di sessione, ma anche una chiave di sessione con crittografia di punteggio elevato. Questa sarà una chiave AES a 128 bit, a sua volta crittografata con una chiave hardcoded nel gioco Flash:

hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))

Ora, prima che il gioco pubblichi il punteggio più alto, decodifica la chiave di sessione di crittografia con punteggio elevato, cosa che può fare perché hai codificato la chiave di sessione di crittografia con punteggio elevato nella chiave di decodifica nel file binario di Flash. Crittografate il punteggio più alto con questa chiave decifrata, insieme all'hash SHA1 del punteggio più alto:

hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))

Il PHP sul server controlla il token per assicurarsi che la richiesta provenga da un'istanza di gioco valida, quindi decodifica il punteggio più alto crittografato, verificando che il punteggio più alto corrisponda allo SHA1 del punteggio alto (se salti questo passaggio, la decrittazione produrrà semplicemente punteggi casuali, probabilmente molto alti, alti).

Quindi ora l'attaccante decompila il tuo codice Flash e trova rapidamente il codice AES, che sporge come un pollice dolente, anche se anche se non lo facesse sarebbe rintracciato in 15 minuti con una ricerca di memoria e un tracciante ("Lo so il mio punteggio per questo gioco è 666, quindi troviamo 666 in memoria, quindi prendiamo qualsiasi operazione che tocchi quel valore --- oh guarda, il codice di crittografia del punteggio più alto! "). Con la chiave di sessione, l'utente malintenzionato non deve nemmeno eseguire il codice Flash; prende un token di lancio del gioco e una chiave di sessione e può restituire un punteggio alto arbitrario.

Ora sei al punto in cui la maggior parte degli sviluppatori si arrende --- dà o impiega un paio di mesi a scherzare con gli aggressori:

  • Scrambling le chiavi AES con XOR

  • Sostituzione di array di byte chiave con funzioni che calcolano la chiave

  • Spargimento di crittografie di chiavi false e registrazioni di punteggi elevati in tutto il file binario.

Questo è tutto principalmente una perdita di tempo. Inutile dire che SSL non ti aiuterà neanche; SSL non può proteggerti quando uno dei due endpoint SSL è male.

Ecco alcune cose che possono effettivamente ridurre le frodi ad alto punteggio:

  • Richiede un accesso per giocare, fare in modo che l'accesso produca un cookie di sessione e non consentire più avvii di gioco in sospeso nella stessa sessione o più sessioni simultanee per lo stesso utente.

  • Rifiuta i punteggi più alti delle sessioni di gioco che durano meno delle partite reali più brevi mai giocate (per un approccio più sofisticato, prova a "mettere in quarantena" i punteggi più alti per le sessioni di gioco che durano meno di 2 deviazioni standard al di sotto della durata media del gioco). Assicurati di tenere traccia delle durate dei giochi sul lato server.

  • Rifiuta o metti in quarantena i punteggi più alti dagli accessi che hanno giocato al gioco solo una o due volte, in modo che gli attaccanti debbano produrre una "traccia cartacea" di gioco dall'aspetto ragionevole per ogni accesso che creano.

  • I punteggi di "Heartbeat" durante il gioco, in modo che il tuo server veda la crescita del punteggio nel corso della vita di un gioco. Rifiuta i punteggi più alti che non seguono curve di punteggio ragionevoli (ad esempio, saltando da 0 a 999999).

  • Stato del gioco "Istantanea" durante il gioco (ad esempio, quantità di munizioni, posizione nel livello, ecc.), Che è possibile riconciliare in seguito con i punteggi intermedi registrati. Non devi nemmeno avere un modo per rilevare anomalie in questi dati per cominciare; devi solo raccoglierlo, e poi puoi tornare indietro e analizzarlo se le cose sembrano sospette.

  • Disabilita l'account di qualsiasi utente che non supera uno dei tuoi controlli di sicurezza (ad esempio, inviando sempre un punteggio elevato crittografato che non supera la convalida).

Ricorda però che stai solo scoraggiando le frodi ad alto punteggio qui. C'è niente che puoi fare per prevenire se. Se ci sono soldi in gioco nel tuo gioco, qualcuno sta per sconfiggere qualsiasi sistema tu abbia inventato. L'obiettivo non è fermare questo attacco; è per rendere l'attacco più costoso del semplice diventare bravo nel gioco e sconfiggerlo.

414
tqbf

Forse stai ponendo la domanda sbagliata. Sembri concentrato sui metodi che le persone usano per risalire la classifica dei punteggi più alti, ma il blocco di metodi specifici va solo così lontano. Non ho esperienza con TamperData, quindi non posso parlarne.

La domanda che dovresti porre è: "Come posso verificare che i punteggi inviati siano validi e autentici?" Il modo specifico per farlo dipende dal gioco. Per giochi puzzle molto semplici, potresti inviare il punteggio insieme allo stato iniziale specifico e alla sequenza di mosse risultanti nello stato finale, quindi rieseguire il gioco sul lato server utilizzando le stesse mosse. Conferma che il punteggio dichiarato è uguale al punteggio calcolato e accetta il punteggio solo se corrispondono.

25
Stephen Deken

Un modo semplice per farlo sarebbe fornire un hash crittografico del tuo valore di punteggio più alto insieme al punteggio stesso. Ad esempio, quando si pubblicano i risultati tramite HTTP GET: http://example.com/highscores.php?score=500&checksum=0a16df3dc0301a36a34f9065c3ff8095

Nel calcolare questo checksum, dovrebbe essere usato un segreto condiviso; questo segreto non dovrebbe mai essere trasmesso sulla rete, ma dovrebbe essere hardcoded sia all'interno del PHP backend che nel frontend flash. Il checksum sopra è stato creato anteponendo la stringa " segreto "al punteggio" 500 ", ed eseguendolo attraverso md5sum.

Sebbene questo sistema impedisca a un utente di pubblicare punteggi arbitrari, non impedisce un "attacco di riproduzione", in cui un utente riposiziona una combinazione di punteggio e hash calcolata in precedenza. Nell'esempio sopra, un punteggio di 500 produrrebbe sempre la stessa stringa di hash. Parte di questo rischio può essere mitigato incorporando ulteriori informazioni (come un nome utente, un timestamp o un indirizzo IP) nella stringa da sottoporre a hash. Sebbene ciò non impedirà la riproduzione dei dati, assicurerà che un set di dati sia valido solo per un singolo utente alla volta.

Per evitare che si verifichi qualsiasi attacco replay, si dovrà creare un tipo di sistema di risposta alla sfida, come il seguente:

  1. Il gioco flash ("il client") esegue un HTTP GET di http://example.com/highscores.php senza parametri. Questa pagina restituisce due valori: un valore salt generato casualmente e un hash crittografico di quel valore di sale combinato con il segreto condiviso. Questo valore salt dovrebbe essere archiviato in un database locale di query in sospeso e dovrebbe avere un timestamp ad esso associato in modo che possa "scadere" dopo forse un minuto.
  2. Il gioco flash combina il valore salt con il segreto condiviso e calcola un hash per verificare che corrisponda a quello fornito dal server. Questo passaggio è necessario per impedire la manomissione dei valori salt da parte degli utenti, in quanto verifica che il valore salt sia stato effettivamente generato dal server.
  3. Il gioco flash combina il valore salato con il segreto condiviso, il valore del punteggio elevato e qualsiasi altra informazione rilevante (soprannome, ip, timestamp) e calcola un hash. Invia quindi queste informazioni a PHP backend tramite HTTP GET o POST, insieme al valore salato, al punteggio più alto e ad altre informazioni.
  4. Il server combina le informazioni ricevute allo stesso modo del client e calcola un hash per verificare che corrisponda a quello fornito dal client. Verifica inoltre che il valore salt sia ancora valido come elencato nell'elenco di query in sospeso. Se entrambe queste condizioni sono vere, scrive il punteggio più alto nella tabella dei punteggi più alti e restituisce un messaggio "successo" firmato al client. Rimuove anche il valore salt dall'elenco delle query in sospeso.

Tieni presente che la sicurezza di una qualsiasi delle tecniche di cui sopra è compromessa se il segreto condiviso è mai accessibile all'utente

In alternativa, è possibile evitare alcuni di questi passaggi avanti e indietro forzando il client a comunicare con il server su HTTPS e assicurando che il client sia preconfigurato in modo da considerare attendibili solo i certificati firmati da un'autorità di certificazione specifica a cui solo l'utente ha accesso .

18
stormlash

Mi piace quello che ha detto tpqf, ma piuttosto che disabilitare un account quando viene scoperto un imbroglio, implementa un honeypot così ogni volta che accedono, vedono i loro punteggi compromessi e non sospettano mai che siano stati contrassegnati come troll. Google per "phpBB MOD Troll" e vedrai un approccio ingegnoso.

11
DGM

Ho fatto una specie di soluzione ... Ho dato un risultato in cui i punteggi sono aumentati (ottieni sempre +1). Innanzitutto, ho iniziato a contare da un numero casuale (diciamo 14) e quando visualizzo i punteggi, ho appena mostrato i punteggi var meno 14. Questo è così se i cracker stanno cercando per esempio 20, non lo troveranno saranno 34 in memoria). In secondo luogo, poiché so quale dovrebbe essere il punto successivo ... Ho usato la libreria di crittografia Adobe, per creare l'hash di quello che sarà il prossimo punto dovrebbe essere. Quando devo incrementare i punteggi, controllo se l'hash dei punteggi incrementati è uguale all'hash che dovrebbe essere. Se il cracker ha cambiato i punti nella memoria, gli hash non sono uguali. Eseguo una verifica lato server e quando ho ottenuto punti diversi dal gioco e dal PHP, so che sono stati coinvolti i trucchi. Ecco lo snippet del mio codice (sto usando Adobe Crypto libraty MD5 class e salt random di crittografia. CallPhp () è la mia validazione lato server)

private function addPoint(event:Event = null):void{
            trace("expectedHash: " + expectedHash + "  || new hash: " + MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt) );
            if(expectedHash == MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt)){
                SCORES +=POINT;
                callPhp();
                expectedHash = MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt);
            } else {
                //trace("cheat engine usage");
            }
        }

Usando questa tecnica + l'offuscamento SWF, sono stato in grado di fermare i cracker. Inoltre, quando invio i punteggi sul lato server, utilizzo la mia piccola funzione di crittografia/decrittografia. Qualcosa del genere (codice lato server non incluso, ma puoi vedere l'algoritmo e scriverlo in PHP):

package  {

    import bassta.utils.Hash;

    public class ScoresEncoder {

        private static var ranChars:Array;
        private static var charsTable:Hash;

        public function ScoresEncoder() {

        }

        public static function init():void{

            ranChars = String("qwertyuiopasdfghjklzxcvbnm").split("")

            charsTable = new Hash({
                "0": "x",
                "1": "f",
                "2": "q",
                "3": "z",
                "4": "a",
                "5": "o",
                "6": "n",
                "7": "p",
                "8": "w",
                "9": "y"

            });

        }

        public static function encodeScore(_s:Number):String{

            var _fin:String = "";

            var scores:String = addLeadingZeros(_s);
            for(var i:uint = 0; i< scores.length; i++){
                //trace( scores.charAt(i) + " - > " + charsTable[ scores.charAt(i) ] );
                _fin += charsTable[ scores.charAt(i) ];
            }

            return _fin;

        }

        public static function decodeScore(_s:String):String{

            var _fin:String = "";

            var decoded:String = _s;

            for(var i:uint = 0; i< decoded.length; i++){
                //trace( decoded.charAt(i) + " - > "  + charsTable.getKey( decoded.charAt(i) ) );
                _fin += charsTable.getKey( decoded.charAt(i) );
            }

            return _fin;

        }

        public static function encodeScoreRand(_s:Number):String{
            var _fin:String = "";

            _fin += generateRandomChars(10) + encodeScore(_s) + generateRandomChars(3)

            return _fin;
        }

        public static function decodeScoreRand(_s:String):Number{

            var decodedString:String = _s;
            var decoded:Number;

            decodedString = decodedString.substring(10,13);         
            decodedString = decodeScore(decodedString);

            decoded = Number(decodedString);

            return decoded;
        }

        public static function generateRandomChars(_length:Number):String{

            var newRandChars:String = "";

            for(var i:uint = 0; i< _length; i++){
                newRandChars+= ranChars[ Math.ceil( Math.random()*ranChars.length-1 )];
            }

            return newRandChars;
        }

        private static function addLeadingZeros(_s:Number):String{

            var _fin:String;

            if(_s < 10 ){
                 _fin = "00" + _s.toString();
            }

            if(_s >= 10 && _s < 99 ) {
                 _fin = "0" + _s.toString();
            }

            if(_s >= 100 ) {
                _fin = _s.toString();
            }           

            return _fin;
        }


    }//end
}

Poi invio la variabile con altri falsi e si perde tra l'altro ... C'è molto lavoro solo per un piccolo gioco flash, ma dove sono coinvolti dei premi alcune persone diventano avide. Se hai bisogno di aiuto, scrivimi un PM.

Saluti, Ico

Nella risposta accettata tqbf menziona che puoi semplicemente fare una ricerca in memoria per la variabile del punteggio ("Il mio punteggio è 666 quindi cerco il numero 666 in memoria").

C'è un modo per aggirare questo. Ho un corso qui: http://divillysausages.com/blog/safenumber_and_safeint

Fondamentalmente, hai un oggetto per memorizzare il tuo punteggio. Nel setter moltiplica il valore che viene passato con un numero casuale (+ e -) e nel getter si divide il valore salvato dal moltiplicatore casuale per recuperare l'originale. È semplice, ma aiuta a fermare la ricerca della memoria.

Inoltre, guarda il video di alcuni dei ragazzi dietro il motore PushButton che parlano di alcuni dei diversi modi in cui puoi combattere l'hacking: http://zaa.tv/2010/12/the-art-of- l'hacking-flash-giochi / . Sono stati l'ispirazione dietro la classe.

4
divillysausages

Non puoi fidarti di alcun dato restituito dal cliente. La convalida deve essere eseguita sul lato server. Non sono uno sviluppatore di giochi, ma realizzo software aziendali. In entrambi i casi possono essere coinvolti soldi e le persone rompono le tecniche di offuscamento lato client.

Forse rispedire periodicamente i dati al server e fare un po 'di validazione. Non concentrarti sul codice client, anche se è qui che risiede la tua candidatura.

3
zeller

La crittografia utilizzando una chiave reversibile (privata) nota sarebbe il metodo più semplice. Non sono completamente su AS, quindi non sono sicuro di quali tipi di provider di crittografia ci siano.

Ma potresti includere variabili come la lunghezza del gioco (crittografate, di nuovo) e un conteggio dei clic.

Tutte le cose come questa possono essere retroingegnerizzate, quindi considera di inserire un mucchio di dati spazzatura per eliminare le persone dall'odore.

Modifica: potrebbe valere la pena ridacchiare in alcune sessioni PHP. Avvia la sessione quando fanno clic su Avvia gioco e (come dice il commento a questo post) registra il tempo. Quando inviano il punteggio può verificare che abbiano effettivamente un gioco aperto e che non stiano inviando un punteggio troppo presto o troppo grande.

Potrebbe valere la pena di elaborare uno scalare per vedere quale sia il punteggio massimo al secondo/minuto di gioco.

Nessuna di queste cose è inconcepibile ma aiuterà ad avere una logica non in Flash dove le persone possono vederla.

3
Oli

Nella mia esperienza, questo è meglio affrontato come un problema di ingegneria sociale piuttosto che un problema di programmazione. Invece di concentrarti sul rendere impossibile imbrogliare, concentrati sul renderlo noioso rimuovendo gli incentivi per imbrogliare. Ad esempio, se l'incentivo principale sono i punteggi più alti pubblicamente visibili, semplicemente ritardare la visualizzazione dei punteggi più alti può ridurre significativamente gli imbrogli rimuovendo il circuito di feedback positivo per gli imbroglioni.

3
Scott Reynen

Stai parlando di quello che viene chiamato il problema della "fiducia dei clienti". Perché il client (in questo denaro, un file SWF in esecuzione in un browser) sta facendo qualcosa per cui è progettato. Salva un punteggio alto.

Il problema è che vuoi assicurarti che le richieste "salva punteggio" provengano dal tuo filmato flash e non da una richiesta HTTP arbitraria. Una possibile soluzione per questo è codificare un token generato dal server nel file SWF al momento della richiesta (utilizzando flasm ) che deve accompagnare la richiesta per salvare un punteggio elevato. Una volta che il server salva quel punteggio, il token è scaduto e non può più essere utilizzato per le richieste.

Il rovescio della medaglia di questo è che un utente sarà in grado di inviare un solo punteggio elevato per ogni caricamento del filmato in flash: devi costringerli a rinfrescare/ricaricare il file SWF prima di poter giocare di nuovo per un nuovo punteggio.

2
Peter Bailey

Il modo in cui lo fa una nuova popolare mod arcade è che invia i dati dal flash a php, di nuovo a flash (o lo ricarica), quindi di nuovo a php. Ciò consente di fare tutto ciò che si desidera confrontare i dati, nonché bypassare hack di dati/decrittazione post e simili. Un modo per farlo è quello di assegnare 2 valori randomizzati da php nel flash (che non è possibile afferrare o vedere anche se si esegue un grabber di dati flash in tempo reale), usando una formula matematica per aggiungere il punteggio con i valori casuali e controllarlo usando la stessa formula per invertirlo per vedere se il punteggio corrisponde quando alla fine va al php. Questi valori casuali non sono mai visibili così come anche i tempi in cui si verifica la transazione e se dura non più di un paio di secondi, lo contrassegna anche come imbroglione perché presume che tu abbia interrotto l'invio per cercare di capire i valori randomizzati o eseguire i numeri attraverso un qualche tipo di cifra per restituire possibili valori casuali da confrontare con il valore del punteggio.

Sembra una buona soluzione se mi chiedi, qualcuno vede qualche problema nell'uso di questo metodo? O possibili modi per aggirarlo?

2
Vaughn

Penso che il modo più semplice sarebbe quello di effettuare chiamate a una funzione come RegisterScore (punteggio) ogni volta che il gioco registra un punteggio da aggiungere e quindi codificarlo, impacchettarlo e inviarlo a uno script php come una stringa. Lo script php saprebbe come decodificarlo correttamente. Ciò fermerebbe qualsiasi chiamata direttamente allo script php poiché qualsiasi tentativo di forzare un punteggio comporterebbe un errore di decompressione.

2
mathieu landry

Ogni volta che il sistema di punteggio elevato si basa sul fatto che l'applicazione Flash invia dati di punteggio elevato non crittografati/non firmati tramite la rete, che possono essere intercettati e manipolati/riprodotti. La risposta segue da ciò: crittografare (decentemente!) O firmare crittograficamente i dati dei punteggi migliori. Questo, almeno, rende più difficile per le persone decifrare il tuo sistema di punteggio elevato perché dovranno estrarre la chiave segreta dal tuo file SWF. Molte persone probabilmente si arrenderanno proprio lì. D'altra parte, tutto ciò che serve è una persona sola per estrarre la chiave e pubblicarla da qualche parte.

Le soluzioni reali comportano una maggiore comunicazione tra l'applicazione Flash e il database dei punteggi migliori, in modo che quest'ultimo possa verificare che un determinato punteggio sia in qualche modo realistico. Questo è probabilmente complicato a seconda del tipo di gioco che hai.

2
Jan Krüger

Non c'è modo di renderlo completamente irremovibile, poiché è facile decompilare i file SWF e un abile hacker sviluppatore potrebbe quindi rintracciare il codice e capire come bypassare qualsiasi sistema crittografato che potresti impiegare.

Se vuoi semplicemente smettere di imbrogliare i bambini tramite l'uso di strumenti semplici come TamperData, allora potresti generare una chiave di crittografia che passi all'avvio a SWF. Quindi usa qualcosa come http://code.google.com/p/as3crypto/ per crittografare il punteggio più alto prima di restituirlo al PHP. Quindi decrittografare alla fine del server prima di memorizzarlo nel database.

2
David Arno

Di solito includo "dati fantasma" della sessione di gioco con la voce punteggio più alto. Quindi, se sto realizzando un gioco di corse, includo i dati di riproduzione. Spesso disponi già dei dati di replay per la funzionalità di replay o per la funzionalità Ghost Race (giocando contro la tua ultima gara o giocando contro il fantasma di tizio # 14 nella classifica).

Controllare questi è un lavoro molto manuale, ma se l'obiettivo è verificare se le prime 10 iscrizioni in un concorso sono legittime, questa può essere un'utile aggiunta all'arsenale di misure di sicurezza che altri hanno già sottolineato.

Se l'obiettivo è mantenere l'elenco dei punteggi migliori online fino alla fine dei tempi senza che nessuno debba guardarli, questo non ti porterà molto.

2
Lucas Meijer

È possibile solo mantenendo tutta la logica di gioco sul lato server che memorizza anche il punteggio internamente senza la conoscenza dell'utente. Per ragioni economiche e scientifiche, l'umanità non può applicare questa teoria a tutti i tipi di gioco escluso il turno. Ad es. mantenere la fisica sul lato server è costoso dal punto di vista computazionale e difficile da rispondere in quanto velocità della mano. Anche possibile, giocando a scacchi chiunque può abbinare il gameplay AI agli avversari. Pertanto, meglio giochi multiplayer dovrebbe contenere anche creatività su richiesta.

2
placeohlder

Non è davvero possibile ottenere quello che vuoi. Le parti interne dell'app Flash sono sempre parzialmente accessibili, specialmente quando sai come usare cose come CheatEngine , il che significa che non importa quanto siano sicure le comunicazioni del tuo sito web e del browser <->, continuerà comunque a essere relativamente semplice da superare.

1
Mark Webster

Potrebbe essere una buona idea comunicare con il backend tramite AMFPHP . Dovrebbe scoraggiare almeno i più pigri dal tentativo di inviare i risultati tramite la console del browser.

1
m1gu3l