Cómo asegurar el servicio web sin iniciar sesión

Tengo una aplicación móvil (actualmente iOS y pronto Android) que habla con un servicio web. No hay login y los datos no son privados. Básicamente, la aplicación publica un marcador (lon, lat) y obtiene los 25 marcadores más cercanos para mostrar en un mapa.

Es una aplicación muy trivial y no puedo imaginarme a nadie poniendo un gran esfuerzo en abusar del servicio web. Sin embargo, puedo ver que hay diversión para alguien en POSTing muchos marcadores. Lo que más me preocupa es alguien que ejecuta un script que envía muchas solicitudes (usa un ancho de banda costoso y no tiene sentido en los datos de mi aplicación).

Estoy llegando lentamente a la conclusión de que esto no puede ser seguro. La mejor respuesta es "no hagas esto". No proporcionar un servicio web sin autenticación. No hay muchos servicios tan abiertos. La API de YouTube de Google está abierta, pero la mayoría no. Lamentablemente, no tengo otra opción. Así que después de días de ver esto, aquí está mi pensamiento. Tenga en cuenta que estoy muy lejos de ser un experto en seguridad y confío en que se pueda mejorar mi enfoque. Pero podría apuntarte en la dirección correcta. Con suerte, alguien con más experiencia podría intervenir y corregir / mejorar esto. encontréEste artículo y comentarios particularmente útiles.

Nivel de mensaje de seguridad

Aseguraré los msgs con un cifrado hash. Todos los clientes y el servicio web conservan una copia de un secreto compartido que se utiliza como sal para crear un hash desde la URL y todos los argumentos de la POST. El hash se pasa como un argumento adicional y el hash se reconstruye y compara en el otro extremo (utilizando la clave compartida como un salt). Esto es bastante bueno hasta que entienda que cualquier código de cliente móvil se puede realizar ingeniería inversa en minutos. En qué punto esta línea de defensa es completamente inútil.

Medidas del cliente

El cliente incluye la limitación de la tasa de mensajes como una medida para restringir la cantidad de mensajes enviados por usuarios honestos. Una vez más, esto es inútil contra un atacante que rompe el dispositivo móvil.

Seguridad del lado del servidor

Por lo tanto, el lado del servidor debe tener tantas medidas de seguridad adicionales como sea posible, por sí solo en el supuesto de que su cliente (y el secreto compartido) esté comprometido. Esto es lo que tengo:

One msg arg es una hora UTC que se utiliza para limitar los ataques de reproducción. Esto debería evitar que un atacante dispare repetidamente el mismo mensaje al servidor.

El servidor realiza la limitación de velocidad por IP. Sí, las IPs son fácilmente falsificadas y el cambio de proxy es un juego de niños, pero todo ayuda cuando tienes tan poco.

Por supuesto, el servidor valida estrictamente todos los argumentos, utiliza consultas parametrizadas y no devuelve excepciones.

Seguridad del nivel de transporte

Desafortunadamente, estoy bastante seguro de que no es posible emitir certificados SSL de clientes individuales sin un proceso de registro. Y porque estoy usando la comprobación de hash msg (y mis datos no son privados) no estoy completamente seguro de lo que SSL trae a la mesa. Sin embargo, probablemente usaré SSL (con un certificado de aplicación amplia) porque agrega otro nivel de seguridad que se implementa de manera fácil y económica (aunque a un costo de tiempo de conexión adicional para cada msg).

El gran gran agujero de Gaping en mi enfoque

Se me advierte que, si la aplicación se vuelve popular, alguien comprometerá el secreto compartido del cliente. Solo porque pueden y probablemente lo publiquen en internet. Así que realmente todo se reduce al lado del servidor. Desafortunadamente,No tengo forma de identificar y bloquear a un atacante.. Esto me encantaría mucho.

Una súplica final

Después de días de investigación, esto es todo lo que tengo. Pero yo quiero más. Apreciaría especialmente cualquier idea para reforzar el lado del servidor. Por lo tanto, he puesto todos mis puntos SO como una recompensa. Sí señor, todos los 97 puntos!