Tengo un servicio que ofrece un bien físico a cambio de dinero o por medio de un código dado por nosotros. Se accede al servicio a través de una aplicación móvil.
Los códigos tienen restricciones de uso, por ejemplo, solo se pueden usar una vez por usuario. Esto se logra enviando un identificador único con la solicitud para verificar si el usuario tiene permiso para usar el código o no.
Esta solución, obviamente, solo funciona en el mundo perfecto, donde nadie realiza ingeniería inversa de su API.
Lo que quiero evitar es que un usuario malintencionado realice una ingeniería inversa de nuestra API de cara al público y ordene una gran cantidad de productos que perjudican gravemente al negocio.
El sistema actual ha evitado esto al tener varias verificaciones en su lugar:
- ID única por usuario, generada en el dispositivo (bypass: generó un UUID aleatorio en cada solicitud maliciosa)
- límite de velocidad, solo se permite una única IP para enviar X solicitudes por Y minutos (desvío: ya que la IP adquirida a través de los encabezados HTTP, esto también debería ser bastante fácil de falsificar, y obviamente solo intervendrá después de que ya haya una cantidad considerable de daño hecho)
¿Cómo puedo asegurarme de que no se abusa de esto?
Las dos únicas soluciones que podría haber encontrado son:
- nunca haga descuentos completos, solo haga descuentos parciales (como 50% de descuento), lo que requeriría que el atacante aún pague por cada bien, reduciendo el incentivo.
- tener cuentas, lo que requeriría más pasos, también reducir el incentivo.
Y para ser honesto, no quiero hacer nada de eso.
Edición 1:
El identificador único se genera en el dispositivo, en iOS el IDFA se usa, en Android, ANDROID_ID
. Se envían como texto simple a través de HTTPS al servidor, para identificar al usuario. Si un usuario malintencionado desea reproducir la solicitud de pedido de productos, solo tiene que cambiar este identificador y el servidor lo aceptará como un nuevo pedido.