2009-11-16 17 views
5

Digamos que en un juego basado en navegador, completando alguna acción (por simplicidad digamos que alguien hace clic en un enlace que aumenta su puntaje en 100) haciendo clic en este enlace que tendría una URL, por ejemplo increase_score.pl?amount=100 qué tipo de prevención es que hay alguien simplemente enviando peticiones al servidor web para ejecutar este comando:prevención de trampas para navegador basado juego xmlhttp/js/perl/php

  1. una y otra vez sin realmente hacer la tarea de hacer clic en el enlace y
  2. Enviando una solicitud falsa al servidor donde la cantidad se establece en algo rediculado como 100000.

Estoy al tanto de comprobar HTTP_REFERER sin embargo, sé que la gente puede evitar eso (no estoy seguro cómo exactamente) y aparte de algunos límites para la segunda opción, estoy un poco perplejo. ¿Alguien alguna vez tiene problemas similares? Soluciones?

+3

Su aplicación debe saber si esa acción está permitida. – Gumbo

+0

Alguien podría simplemente enviar la secuencia de solicitudes al servidor que les permita llegar al punto donde esa acción está permitida aunque – user105033

+0

Entonces su servidor no debería dar los puntos. –

Respuesta

15

Nada puede evitar que hagan esto si implementa su juego como lo propone.

Debe implementar la lógica del juego en el servidor y asignar puntos solo una vez que el servidor valida la acción.

Por ejemplo: en SO cuando alguien vota su pregunta, esto no se envía como un comando para aumentar su reputación. La aplicación web simplemente le dice al usuario del servidor X que votó la pregunta Y hacia arriba. El servidor luego valida los datos y asigna los puntos si todo sale bien. (Por no decir SO es un juego, pero la lógica requerida es similar.)

+5

¿Qué? SO no es un juego? –

+4

@JB: Jajajaja, sí lo es ... ¡y mi puntaje es ** más de 9000 **! : D – Powerlord

+0

@JB: por supuesto que no. Es simplemente una comunidad con un mecanismo para - ¡oye! ¡Casi tengo mi puntaje hasta 700! Vamos, solo un voto más para el número de la ronda grande, ven a papá ... – BlairHippo

1

Token con cookie/sesión.

1

Puede hacer que el enlace sea dinámico y tener un hash que cambie al final. Verifique que el hash sea correcto dado ese período de tiempo.

Esto podría variar en complejidad dependiendo de la frecuencia con la que permitió los clics.

3

La lógica del juego (aplicación) debe basarse en la regla de no confiar en nada que provenga del usuario.

HTTP_REFERER se puede falsificar con cualquier cliente web.

+0

Oh, sí, nunca confíes en el cliente ... – sleske

0

Ampliando la respuesta de Ahmet, cada vez que cargan una página, generan una clave aleatoria. Almacene la clave en la sesión del usuario. Añadir la clave aleatoria a cada enlace, por lo que el nuevo enlace para conseguir esos 100 puntos es:

increase_score.pl?amount=100&token=AF32Z90 

Cuando se hace clic en cada enlace, comprobar para asegurarse de que el token coincida con la de la sesión, y luego hacer una nueva clave y guárdela en la sesión. Una nueva clave aleatoria para cada vez que hacen una solicitud.

Si te dan la clave incorrecta, intentan volver a cargar una página.

+0

Simplemente no prohibas a las personas por hacer esto - hay razones legítimas para volver a cargar una página, como intentar ver si algo cambió, o reiniciar el navegador. –

+0

Lo que ha hecho es que su aplicación sea más complicada y requirió la complejidad correspondiente en un programa de trampa. Esta no es una carrera armamentista en la que desees participar, ya que los tramposos tienen efectivamente un tiempo ilimitado para estudiar tu Javascript y no puedes cambiarlo en tiempo real para responder. –

+0

En realidad, esto podría causar un problema: si el usuario llega a una página con dicho enlace y lo actualiza, el valor aleatorio cambiará y el enlace se volverá no legítimo cuando nunca se haya hecho clic. –

0

Sugeriría hacer una URL específica para cada acción. Algo a lo largo de las líneas de:

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

Cada uno de estos enlaces puede hacer dos cosas:

  1. Marcos en la sesión que el enlace se ha hecho click modo que no lo puedo realizar un seguimiento de ese vínculo de nuevo.
  2. Añadir a la puntuación.
+1

Esto no se escalaría bien y ofuscaría innecesariamente la aplicación. –

+0

Ofuscación de URL es lo que estaba buscando. Simplemente haga que sea más difícil para el jugador modificar la URL y obtener una ventaja de puntaje. Tengo curiosidad de por qué esto no se escalaría bien, sin embargo? Un controlador mod_perl que analiza los puntajes y envía a una llamada a un método parece que se escalaría muy bien. –

4

Versión corta: no se puede. Cada pieza de información que obtienes del cliente (navegador) puede ser falsificada manualmente por alguien que sabe lo que está haciendo.

Tiene que volver a pensar fundamentalmente cómo se estructura la aplicación. Necesita codificar el lado del servidor de la aplicación de tal manera que trate cada dato proveniente del cliente como un paquete de sucias y asquerosas mentiras hasta que pueda probarse que los datos son, de hecho, plausibles. Debe evitar dar al servidor la mentalidad de "Si el cliente me dice que haga esto, claramente fue permitido para decirme que haga esto".

MANERA INCORRECTA:
Cliente: Jugador Steve dice para dar jugador Steve uno tropecientos puntos.
Servidor: ¡Bien!

manera correcta:
Cliente: Jugador Steve dice para dar jugador Steve uno tropecientos puntos.
Servidor: Bueno, permítanme comprobar primero si el Jugador Steve, en este momento, puede darse un tropecientos puntos ... ah. Él no es. Muestre este mensaje "Go Fsck Yourself, Cheater" al Jugador Steve.

En cuanto a decir quién ha iniciado sesión, es una simple cuestión de entregarle al cliente una cookie con un valor casi imposible de adivinar del que puede hacer un seguimiento en el servidor, pero supongo que saber cómo lidiar con la gestión de sesiones. :-) (Y si no lo hace, Google awaits.)

+0

Papá, ahí está tu gran número redondo. –

1

Algunas cosas a tener en cuenta aquí.

Primero, las solicitudes de su servidor para algo como esto deberían ser POST, no GET. Solo las solicitudes GET deben ser idempotentes, y no hacerlo es realmente a violation of the HTTP specification.

En segundo lugar, lo que está buscando aquí es el clásico Client Trust Problem. Usted tiene para confiar en el cliente para enviar puntajes u otra información de intervalo de juego al servidor, pero no desea querer que el cliente envíe datos ilegítimos. La prevención de acciones no permitidas es fácil, pero prevenir los datos de juego sucio en una acción permitida es mucho más problemático.

Ben S hace una buena idea acerca de cómo se diseñan los protocolos de comunicación entre un cliente y un servidor como este. Permitir que los valores de puntos se envíen como datos confiables generalmente será una mala idea. Es preferible indicar que se realizó una acción, y dejar que el servidor determine cuántos puntos se deben asignar, si es que se debe asignar. Pero a veces no puedes evitar eso. Considera el escenario de un juego de carreras. El cliente tiene para enviar la hora del usuario y no puede ser abstraída en otra llamada como "completedLevelFour". ¿Entonces que haces ahora?

El enfoque simbólico que sugieren Ahmet y Dean es el sonido, pero no es perfecto. En primer lugar, el token todavía tiene que ser transmitido al cliente, lo que significa que es detectable por el atacante potencial y podría ser utilizado maliciosamente. Además, ¿qué pasa si tu API del juego debe ser apátrida? Eso significa que la autenticación de token basada en la sesión está fuera. Y ahora te metes en las entrañas profundas y oscuras del problema de confianza del cliente.

Hay muy poco que puede hacer para que sea 100% infalible. Pero puede hacerlo muy inconveniente para hacer trampa. Considere el modelo de seguridad de Facebook (todas las solicitudes API están firmadas). Esto es bastante bueno y requiere que el atacante profundice realmente en el código del lado del cliente antes de que pueda descubrir cómo suplantar un error.

Otro enfoque es la reproducción del servidor. Como en un juego de carreras, en lugar de tener un valor de "tiempo" enviado al servidor, tenga puntos de control que también registren el tiempo y los envíen todos. Establezca mínimos realistas para cada intervalo y verifique en el servidor que todos estos datos se encuentran dentro de los límites establecidos.

¡Buena suerte!

1

Parece que un componente de tu juego necesitaría solicitar aceleración. Básicamente, realiza un seguimiento de qué tan rápido está accediendo un cliente en particular a su sitio y comienza a ralentizar sus respuestas a ese cliente cuando su tasa excede lo que cree que es razonable. Hay varios niveles de eso, comenzando en los filtros IP de bajo nivel hasta algo que maneja en el servidor web. Por ejemplo, Stackoverflow tiene un poco en la aplicación web que capta lo que cree que son demasiadas ediciones demasiado juntas. Te redirige a un captcha al que debes responder si deseas continuar.

En cuanto a los demás bits, debe validar toda la entrada no solo por su forma (por ejemplo, es un número) sino también porque el valor es razonable (por ejemplo, menos de 100 o lo que sea). Si ve a un cliente haciendo algo gracioso, recuerde eso. Si atrapa al mismo cliente haciendo algo divertido a menudo, puede prohibirlo.

0

Si desea que el juego solo se ejecute en su servidor, también puede detectar desde dónde se envía la señal en su truco de recepción e ignorar cualquier cosa que no provenga de su dominio. Sería un verdadero dolor alterar sus códigos, si tiene que ejecutar desde su dominio dedicado para enviar puntajes.

Esto también bloquea la mayoría de los trucos de CheatEngine.

+0

El juego (al menos la parte de interacción del usuario) todavía se ejecutará en el lado del cliente, no en el servidor. No veo cómo puedes bloquear esto. –

Cuestiones relacionadas