Evita l'aggiornamento non autorizzato della classifica online php / sql [duplicato]

5

Sto sviluppando un'applicazione web offline (gioco) per Android che utilizza cordova (PhoneGap). La classifica della stessa viene mantenuta online nel mio server.

Attualmente questo è il modo in cui la classifica è aggiornata

Passaggio 1) Il punteggio dell'utente viene archiviato nella memoria locale dell'app offline.

Passaggio 2) L'utente preme il pulsante "aggiorna il mio punteggio" collegandosi a Internet.

Passaggio 3) Il pulsante invia sostanzialmente una richiesta Ajax a link

Passaggio 4) Sulla base di questo il database viene aggiornato nel mio server dal file scoreupdate.php e restituisce successo.

Questi sono i problemi che sto affrontando

1) Chiunque può visitare facilmente link se conosce l'id utente (può essere facilmente ottenuto dai dati di localstorage dell'app) e lui / lei può aggiornare il suo punteggio nella classifica semplicemente sostituendo il valore ottenuto con il valore alto con un valore elevato per ottenere una posizione migliore in classifica.

2) Qualsiasi valore segreto memorizzato nell'app o nella cronologia locale può essere ottenuto facilmente poiché l'intero oggetto è costruito in javascript. È anche possibile eseguire il reverse engineering dell'applicazione in modo da non riuscire a trovare un modo per autenticare in modo efficiente che sia l'app reale che sta inviando la richiesta al server e non a una persona.

I miei requisiti

1) L'app deve essere in grado di autenticare il file scoreupdate.php che è l'app reale e non una persona. In modo che solo l'app sarà in grado di aggiornare la classifica.

2) La logica dell'autenticazione non deve essere violata dall'utente semplicemente leggendo il codice sorgente dell'app. (es: moltiplicando l'id utente con alcuni numeri e facendo il processo inverso nel server non funzionerà)

C'è un modo per farlo?

Il rimescolamento di Javascript non è efficace in quanto può essere facilmente decodificato

Modifica

Non sono preoccupato se qualcuno ruba le credenziali dell'utente tramite un MITM o qualsiasi attacco di tipo bruteforce. Anche il vero utente che possiede il profilo non dovrebbe essere in grado di aggiornare il proprio punteggio.

    
posta Sandeep Thedarkprince C 31.12.2015 - 19:09
fonte

5 risposte

7

Non sono d'accordo che sia impossibile.

A seconda della forma del tuo gioco potrebbe essere possibile applicare il seguente schema:

  1. Durante il gioco, registra lo stato iniziale, comprese le sementi sugli RNG e tutti gli input dell'utente.
  2. Quando invii il gioco, invia questo "replay" della sessione al server insieme al punteggio richiesto.
  3. Sul server, esegui la logica di gioco con l'input fornito e verifica se risulta nello stesso punteggio. Se lo fa, il replay è valido e tu aggiorni il punteggio.

In questo modo, hai efficacemente trasformato il problema del barare nel problema di scrivere un bot o un risolutore per il tuo gioco, il meglio che puoi mai ottenere in una situazione come questa.

Fondamentalmente questa è un'ottima soluzione per tutti i giochi che possono essere visti come un problema NP-completo in cui la verifica di una soluzione è computazionalmente semplice, mentre trovarla è computazionalmente difficile. Uno di questi esempi è Sokoban.

    
risposta data 01.01.2016 - 00:40
fonte
6

No, questo è impossibile.

Stai facendo affidamento sul cliente per fornire dati accurati. Ma non puoi farlo perché il cliente è fuori dal tuo controllo. Funziona sull'hardware degli utenti, il che significa che l'utente può cambiarlo nel modo desiderato e non c'è nulla che tu possa fare al riguardo. Qualsiasi tentativo di autenticare che il client non è stato modificato deve essere eseguito anche sul computer client, il che significa che non è protetto nemmeno dalla manipolazione.

L'unico modo per impedire ai giocatori di barare è eseguire tutte le meccaniche di gioco sul tuo server.

    
risposta data 31.12.2015 - 20:46
fonte
3

Con un'applicazione offline questo non può essere raggiunto perché ti costringe a fidarti dell'applicazione (che può essere modificata) per archiviare e aggiornare il punteggio. Non c'è modo di aggirare questo per un'applicazione offline.

Anche con la crittografia completamente omomorfica, l'applicazione offline sarebbe in grado di manomettere i dati anche se non può vedere i dati originali.

Se l'applicazione client è responsabile della conservazione dei punteggi, puoi solo sperare in onestà e frustrare i tentativi di inganno tramite l'offuscamento; in realtà non puoi impedirli.

Una possibile soluzione incompleta che può indirizzare un'alta percentuale di barare sta usando reti bayesiane sintonizzate per eseguire il rilevamento delle frodi. Valutate i cambiamenti nell'attività di gioco e registrate le modifiche in secchi bassi, medi e alti e quindi usate una rete bayesiana per fondere i risultati in un singolo punteggio di rischio. È piuttosto sofisticato e non infallibile, ma potrebbe essere un'opzione se l'app deve essere offline.

Se puoi renderlo un'applicazione online, puoi invece spostare la gestione delle regole e il mantenimento del punteggio sul server che è sotto il tuo controllo, dove puoi evitare di barare. Anche in questo caso è ancora un processo complicato se il client è in grado di inviare qualcosa di più degli eventi di input dell'utente.

    
risposta data 31.12.2015 - 21:04
fonte
1

Mi dispiace, non posso farlo.

In generale, se i tuoi requisiti sono:

  1. Avere un client offline.
  2. Rendi il codice client open source o facilmente decompilabile.
  3. Impedisci al cliente di barare.

Quindi, scegli qualsiasi 2 di questi .

Nota: anche se decidi di cambiare # 2 e andare con un codice compilato che non è facilmente decompilabile, sei ancora in balia della sicurezza per oscurità. Puoi crittografare le chiavi del codice e sperare che nessuno lo capisca mai, e se il tuo gioco è solo per divertimento potrebbe essere abbastanza buono , ma se il denaro è coinvolto potrebbe non esserlo.

L'opzione migliore del 3 per cambiare è non avere un client offline.

Avvertenza: sopra ho detto "in generale" perché ci sono tipi specifici di giochi in cui puoi soddisfare tutti e 3 i requisiti, ad esempio i giochi che sono intrinsecamente difficili da risolvere (ad esempio, immagina un tipo di Cubo di Rubik gioco in cui la soluzione non è ancora ampiamente conosciuta). Vedi la risposta di Zeta Two per ulteriori informazioni su questi tipi di domande.

    
risposta data 31.12.2015 - 20:53
fonte
0

L'unico vero modo per risolverlo è con hardware personalizzato in cui le chiavi crittografiche e il codice sorgente sono incorporati in un dispositivo in un modo che è molto difficile per gli utenti normali di estrarre o modificare.

Ad esempio, potresti avere un sistema di videogiochi in cui legge i giochi su DVD criptati. Il sistema di videogiochi (che esegue il codice sorgente segreto esistente nella memoria di sola lettura sul sistema) può decifrare il videogioco (utilizzando una chiave segreta incorporata nel dispositivo) e verificare che provenga da una fonte legittima e non sia stato modificato. All'interno del codice sorgente del videogioco (che il sistema verificato non è stato modificato e non può essere trapelato), è possibile includere una chiave privata utilizzata per firmare digitalmente combinazioni di nome utente e punteggi elevati quando si inviano i punteggi alla classifica online.

Tuttavia, una volta che permetti agli utenti di visualizzare e modificare il codice sorgente, hai perso (dato che l'utente può semplicemente modificare la fonte per cambiare il punteggio più alto a qualsiasi valore immediatamente prima della normale consegna del punteggio), a meno c'è un modo per l'utente di inviare le proprie mosse e fare in modo che il server verifichi che quelle mosse corrispondano al punteggio.

Ad esempio, se il gioco prevede la risoluzione di enigmi in X mosse o meno, e vuoi sottomettere l'ennesimo puzzle N-esimo, puoi fare in modo che il tuo gioco invii la serie di mosse che hai fatto, quindi il tuo server può controlla che quelle mosse consistano in una soluzione che risolve l'ennesimo enigma in X mosse o meno e che è stato inviato al momento indicato dall'orologio del server.

    
risposta data 31.12.2015 - 21:33
fonte