2009-11-16 8 views
5

Diciamo che in un gioco basato su browser, completando qualche azione (per semplicità diciamo che qualcuno clicca su un link che aumenta il loro punteggio di 100) cliccando su questo link che avrebbe un URL, ad esempio increase_score.pl?amount=100 quale tipo di prevenzione è lì da qualcuno semplicemente inviando le richieste al server web per eseguire questo comando:cheat prevention per il gioco xmlhttp/js/perl/php basato su browser

  1. più e più volte senza fare il compito di cliccare sul link e
  2. Invio di una richiesta errata al server in cui l'importo è impostato su qualcosa di simile a 100000.

Sono a conoscenza del controllo di HTTP_REFERER tuttavia so che le persone possono aggirare il problema (non sono sicuro di come esattamente) e oltre ad alcuni limiti che controllano la seconda opzione, sono un po 'stonato. Qualcuno ha mai avuto problemi simili? Soluzioni?

+3

L'applicazione deve sapere se tale azione è consentita. – Gumbo

+0

Qualcuno potrebbe semplicemente inviare la sequenza di richieste al server che consente loro di arrivare al punto in cui tale azione è consentita anche se – user105033

+0

Quindi il server non dovrebbe effettivamente fornire i punti. –

risposta

15

Nulla può impedirgli di eseguire questa operazione se si implementa il gioco come si propone.

È necessario implementare la logica di gioco sul server e assegnare i punti solo quando il server convalida l'azione.

Ad esempio: su SO quando qualcuno vota la tua domanda, questo non viene inviato come comando per aumentare la tua reputazione. L'app web dice solo all'utente del server X ha votato la domanda Y up. Il server quindi convalida i dati e assegna i punti se tutto si verifica. (Per non dire che SO è un gioco, ma la logica richiesta è simile.)

+5

Cosa ?! SO non è un gioco ?! –

+4

@JB: Hahahaha, sì è ... e il mio punteggio è ** oltre 9000 **! : D – Powerlord

+0

@ JB: Certo che no. È semplicemente una comunità con un meccanismo per - hey! Ho quasi raggiunto il mio punteggio fino a 700! Dai, solo un altro voto per il numero tondo, vieni da papà .... – BlairHippo

1

Token con cookie/sessione.

1

Si potrebbe rendere dinamico il collegamento e avere un hash che è cambiato alla fine di esso. Verifica che l'hash sia corretto dato quel periodo di tempo.

Questo potrebbe variare in complessità a seconda della frequenza con cui hai consentito i clic.

3

La logica del gioco (applicazione) deve essere basata sulla regola per non fidarsi di nulla che proviene dall'utente.

HTTP_REFERER può essere contraffatto con qualsiasi client Web.

+0

Oh sì, non fidarti mai del cliente ... – sleske

0

Espansione della risposta di Ahmet, ogni volta che caricano una pagina, genera una chiave casuale. Memorizza la chiave nella sessione utente. Aggiungere la chiave casuale per ogni link, in modo che il nuovo collegamento per ottenere quei 100 punti è:

increase_score.pl?amount=100&token=AF32Z90 

Quando ogni link viene cliccato, controllare per assicurarsi che il token corrisponde a quello nella sessione, e poi fare un nuova chiave e memorizzarla nella sessione. Una nuova chiave casuale per ogni volta che fanno una richiesta.

Se ti danno la chiave sbagliata, stanno cercando di ricaricare una pagina.

+0

Basta non vietare le persone per farlo - ci sono motivi legittimi per ricaricare una pagina, come provare a vedere se qualcosa è cambiato, o riavviare il browser. –

+0

Ciò che hai fatto è reso la tua app più complicata e ha richiesto la corrispondente complessità in un programma cheat. Questa non è una corsa agli armamenti in cui vuoi entrare, dato che i truffatori hanno effettivamente tempo illimitato per studiare il tuo Javascript e non puoi cambiarlo in tempo reale per rispondere. –

+0

In realtà, questo potrebbe causare un problema: se l'utente arriva a una pagina con tale collegamento e si aggiorna, il valore casuale cambierà e il collegamento diventa non valido quando non è mai stato fatto clic. –

0

Suggerirei di creare un URL specifico per ogni azione. Qualcosa sulla falsariga di:

/score/link_88_clicked/ 
/score/link_69_clicked/ 
/score/link_42_clicked/ 

Ognuno di questi collegamenti può fare due cose:

  1. Mark nella sessione che il link è stato cliccato in modo che non ci vorrà traccia che puntano di nuovo.
  2. Aggiungi al loro punteggio.
+1

Questo non si ridimensiona bene e offusca inutilmente l'applicazione. –

+0

L'offuscamento dell'URL è quello che cercavo. Basta rendere più difficile per il giocatore modificare l'URL e ottenere un vantaggio di punteggio. Sono curioso di sapere perché questo non potrebbe scalare bene, comunque? Un gestore mod_perl che analizza i punteggi e che invia a una chiamata di metodo sembra che si ridimensionerà perfettamente. –

4

Versione corta: non è possibile. Ogni pezzo di dati che si ottiene dal client (browser) può essere manualmente falsificato da qualcuno che sa cosa sta facendo.

È necessario riflettere fondamentalmente come è strutturata l'applicazione. È necessario codificare il lato server dell'app in modo tale da trattare ogni pezzo di dati proveniente dal client come un branco di sporche bugie fasulle fino a quando non può dimostrare a se stesso che i dati sono, in realtà, plausibili. È necessario evitare di dare al server una mentalità di "Se il client mi dice di fare questo, chiaramente era permesso a di dirmi di fare questo".

MODO SBAGLIATO:
Cliente: Player Steve dice di dare Player Steve uno punti gazillion.
Server: OK!

strada giusta:
Cliente: Player Steve dice di dare Player Steve uno punti gazillion.
Server: Bene, prima controlliamo se Giocatore Steve è, in questo momento, concesso a darsi un punteggio di gazillion ... ah. Lui non lo è. Si prega di visualizzare questo messaggio "Go Fsck Yourself, Cheater" a Player Steve.

Come per dire chi ha effettuato l'accesso, è una semplice questione di consegnare al cliente un cookie con un valore praticamente impossibile da indovinare che si tiene traccia del server - ma assumerò che tu sapere come gestire la gestione delle sessioni. :-) (E se non lo fai, Google awaits.)

+0

Papà, c'è il tuo numero tondo. –

1

Alcune cose da notare qui.

In primo luogo, le richieste del server per qualcosa di simile dovrebbero essere POST, non GET. Solo le richieste GET dovrebbero essere idempotenti, e il fatto di non farlo è in realtà a violation of the HTTP specification.

In secondo luogo, quello che stai guardando qui è il classico Problema di affidabilità del client. È necessario a fidarsi del client per inviare i punteggi o altre informazioni di gioco-intervallo al server, ma non si desidera che il client di inviare i dati illegittimi. Prevenire le azioni non consentite è facile, ma impedire che i dati di foul-play in un'azione consentita siano molto più problematici.

Ben S è un ottimo punto su come si progettano i protocolli di comunicazione tra un client e un server come questo. Permettere valori del punto da inviare come dati di fiducia è generalmente sarà una cattiva idea. È preferibile indicare che è stata eseguita un'azione e lasciare che il server mostri quanti punti assegnare, se non del tutto. Ma a volte non puoi andare in giro. Considera lo scenario di un gioco di corse. Il client ha per inviare l'ora dell'utente e non può essere estratto in un'altra chiamata come "completatoLivelloFour". Quindi cosa fai adesso?

L'approccio token che Ahmet e Dean suggeriscono è suono - ma non è perfetto. In primo luogo, il token ancora deve essere trasmesso al cliente, che significa che è rilevabile dal potenziale attaccante e potrebbe essere usato maliziosamente. Inoltre, cosa succede se la tua API di gioco deve essere stateless? Ciò significa che l'autenticazione token basata su sessione è fuori. E ora entri nelle profondità e nelle tenebre del Problema della Client Trust.

C'è pochissimo che puoi fare rendilo sicuro al 100%. Ma puoi renderlo molto scomodo per imbrogliare. Considera il modello di sicurezza di Facebook (ogni richiesta API è firmata). Questo è abbastanza buono e richiede che l'utente malintenzionato scriva effettivamente nel codice lato client prima di poter capire come spoofare un reqeust.

Un altro approccio è la ripetizione del server. Come per un gioco di corse, invece di avere solo un valore di "tempo" inviato al server, avere dei checkpoint che registrano anche il tempo e li inviano tutti. Stabilire minimi realistici per ciascun intervallo e verificare sul server che tutti questi dati rientrino nei limiti stabiliti.

Buona fortuna!

1

Sembra che un componente del gioco necessiti di una limitazione richiesta. Fondamentalmente, tieni traccia della velocità con cui un determinato cliente accede al tuo sito e inizi a rallentare le tue risposte a quel cliente quando la loro velocità supera quella che ritieni ragionevole. Ci sono vari livelli di questo, a partire dai filtri IP di basso livello fino a qualcosa che gestisci nel server web. Ad esempio, Stackoverflow ha un po 'nell'applicazione web che cattura quelle che pensa siano troppe modifiche troppo ravvicinate. Ti reindirizza a un captcha a cui devi rispondere se vuoi continuare.

Come per gli altri bit, è necessario convalidare tutto l'input non solo per la sua forma (ad esempio è un numero) ma anche che il valore è ragionevole (ad esempio inferiore a 100 o qualsiasi altra cosa). Se vedi un cliente fare qualcosa di divertente, ricordalo. Se riesci a catturare lo stesso cliente facendo spesso qualcosa di divertente, puoi vietarlo.

0

Se vuoi che il gioco funzioni solo sul tuo server, puoi anche scoprire da dove viene inviato il segnale nel tuo dispositivo di ricezione e ignorare tutto ciò che non proviene dal tuo dominio. Sarà un vero dolore manomettere i tuoi codici, se devi correre dal tuo dominio dedicato per inviare i punteggi.

Questo blocca anche la maggior parte dei trucchi di CheatEngine.

+0

Il gioco (almeno la parte di interazione dell'utente) continuerà a funzionare sul lato client, non sul server. Non vedo come puoi bloccarlo. –