¿Cómo proteger la autenticación REST JWT para que no acepte llamadas desde el navegador?

2

He creado un sistema cliente-servidor REST simple con tokens JWT.

En mi aplicación móvil, puedes intercambiar tu token de acceso de Facebook / Google por un JWT con el servidor y luego hacer llamadas con él, por ejemplo. trae a tus amigos / datos en la aplicación.

Ahora, quiero limitar esto para que el servidor acepte solo las respuestas publicadas a través de la aplicación de Android, no el navegador web clásico.

Este escenario puede suceder cuando, por ejemplo, el usuario publica su solicitud POST a través de una aplicación como Cartero para Chrome.

¿Cómo manejas este tipo de cosas?

    
pregunta Spectre 24.01.2017 - 12:34
fuente

3 respuestas

3

Parece que lo que estás tratando de hacer es identificar el software que se usa para acceder a tu API. La forma en que veo esto, es independiente de la autenticación del usuario. La autenticación de usuario le dice a usted quién está usando su API, está interesado en qué se está usando para acceder a su API.

El problema fundamental al que se enfrenta es que no puede confiar al 100% en el código que se ejecuta en el cliente. No tienes control sobre él y un usuario malintencionado puede modificarlo o realizar ingeniería inversa o, como sugeriste, usar algo como Postman para enviar solicitudes sintéticas.

Tiene varias opciones para proceder:

Eliminar el problema

Puede ser que puedas volver a diseñar tu aplicación y servidor para que ya no te importe lo que se usa para acceder a tu API. Es difícil confiar en el código que no controla, por lo que, si es posible, es bueno mover la mayor parte de la funcionalidad al servidor.

Cadena de agente de usuario

Un método básico para intentar identificar el origen de una solicitud es mirar la cadena de agente de usuario que se incluye en los encabezados de las solicitudes que llegan a su API. Podrías filtrar solicitudes provenientes de cosas que no son tu aplicación de Android. El problema es que es solo un encabezado y es realmente sencillo de falsificar. Así que no hace mucho en la práctica.

Clave de API (y Secreto)

Otra cosa que podrías hacer sería usar una clave API. Este es un identificador que utiliza para que su servidor sepa que el cliente que accede a él es genuino. Para evitar que se lo roben simplemente observando la conexión con un proxy, debe usar TLS, que encripta la conexión entre el cliente y el servidor para que terceros no puedan escucharlos fácilmente. Sin embargo, todavía puede ser vulnerable a un ataque de hombre en el medio (consulte pinning si esto es un preocupación).

Puede mejorar este esquema combinando o reemplazando su clave con un secreto que almacena en la aplicación y nunca transmite. En su lugar, firma el tráfico que envía a la API utilizando un HMAC. Si alguien altera el mensaje que envía, la firma no coincidirá y puede rechazar la solicitud. Debido a que su aplicación es lo único con el secreto, otra aplicación no podrá acceder a su API.

Esto es válido siempre y cuando su secreto permanezca oculto, pero si ha liberado su aplicación, un malicioso puede potencialmente obtener acceso a la aplicación e intentar verla para recuperar el secreto. Lo difícil que es esto depende de lo difícil que lo escondas. Puede ofuscar su secreto o insertarlo en el código nativo, pero una persona suficientemente motivada probablemente podrá encontrarlo con suficiente tiempo.

En conclusión

Ninguna de las opciones para identificar la fuente de una llamada a la API es perfecta, la gente le dirá con razón que todas pueden ser resquebrajadas. La decisión que debe tomar es cuán importante es lo que tenga detrás de su API y cuánto desea protegerla. Solo tú puedes responder a eso.

Trabajo en un lugar que hace este tipo de cosas y uno de mis colegas acaba de comenzar a escribir una serie de artículos que detallan un poco más sobre seguridad de API móvil . Si desea más detalles, puede ser de su interés.

    
respondido por el ThePragmatist 25.01.2017 - 23:23
fuente
1

Hay algunas formas en que puedes lograr esto. Espero que su objetivo sea aceptar solicitudes solo de clientes conocidos?

Clave previamente compartida

Un PSK en su forma más simple es una clave que se intercambia entre dos partes fuera de banda con el remitente que usa la clave compartida tal como está en los mensajes como credencial. Por esta razón, HTTPS generalmente es una necesidad para los PSK. Sin ayuda Desde la seguridad del transporte, es más fácil para un usuario malintencionado obtener el PSK y utilizarlo en una solicitud maliciosa, al igual que una solicitud legítima.

Marca de tiempo para evitar ataques de reproducción

Supongamos que diseñamos nuestro mecanismo de seguridad para transmitir las credenciales, no en texto sin formato, sino encriptadas mediante el PSK. La credencial cifrada se envía en el mensaje, generalmente en el encabezado de solicitud HTTP. Un usuario malicioso no puede descifrar el encabezado y extraiga las credenciales, pero puede reproducir la solicitud anterior tal como está. Peor aún, un usuario malicioso puede encuadrar un nuevo solicite y use solo el valor del encabezado que contiene las credenciales válidas de la solicitud exitosa anterior.

Se puede agregar una marca de tiempo al mensaje y cifrarse junto con el resto del contenido del mensaje. El servicio puede recupera la marca de tiempo después de descifrar el mensaje y falla la solicitud si la marca de tiempo es demasiado antigua para el umbral eso ya está acordado. Esto reduce la ventana de oportunidad para reproducir una solicitud.

El inconveniente es que tanto el servidor como el cliente deben sincronizarse con el tiempo.

Una alternativa a una marca de tiempo es un contador como el contador de nonce que vimos con la autenticación de resumen. Con un contador, no debemos preocuparnos por el sesgo entre los relojes. Sin embargo, los clientes deben implementar un contador para garantizar que el recuento enviado en una solicitud sea mayor que el recuento en la solicitud anterior al menos en uno, y el El servidor debe mantener un registro del último contador recibido. Por supuesto, el mensaje debe ser firmado para que un usuario malintencionado no incrementa el contador y repite el resto de la solicitud.

Evitar el mal uso del identificador

En su forma más simple, un PSK es tanto el identificador de usuario como la credencial. Por esta razón, los PSK deben ser únicos. Dado un Clave, una aplicación debe ser capaz de identificar al usuario correspondiente sin ninguna ambigüedad. La premisa básica que tenemos están trabajando en evitar el HTTPS. Por esta razón, el PSK no se puede transmitir como está. Necesitamos tener dos claves: una que actúa como la identidad del usuario y la otra que actúa como la credencial.

Sin embargo, estas claves no están vinculadas matemáticamente. Además, la misma clave utilizada para firmar en el extremo del remitente se usa para validar la firma en el extremo del receptor; Por lo tanto, esto es sólo una clave compartida simétrica. Pero similar a la clave pública Criptografía, solo la clave privada debe estar protegida.

Prevenga los ataques MIM (para comunicaciones que no sean HTTPS)

Sin HTTPS, un ataque Man-in-the-middle (MITM) es una de las amenazas más importantes. El mecanismo primario para garantizar la integridad de los datos de los mensajes es un Código de autenticación de mensajes basado en Hash (HMAC). HMAC es solo una pieza de datos creados a través de un algoritmo de hash criptográfico y una clave secreta compartida. En esta sección, te muestro cómo para crear un HMAC usando el algoritmo SHA256. Sin embargo, si el mensaje debe cifrarse por confidencialidad, puede agregar fácilmente esa funcionalidad utilizando la misma clave privada que usamos para HMAC o puede introducir una nueva clave específicamente para el cifrado.

La solicitud debe contener los siguientes parámetros

  • La clave pública, que es la clave asociada con el usuario.
  • El contador
  • La marca de tiempo

Además de los parámetros, la solicitud incluye una firma que garantiza que ninguno de los parámetros sea manipulado. Es posible crear la firma basándose no solo en los tres parámetros, sino también en todo el cuerpo. de la solicitud si el objetivo es asegurarse de que no se modifique nada en la solicitud.

Para asegurarnos de que nadie manipule los parámetros, podemos incluir un HMAC-SHA256 de los tres valores más el Solicitud de URI y método HTTP. El listado 9-1 muestra una solicitud HTTP protegida por el mecanismo PSK. La figura 9-2 muestra El diseño de PSK.

    
respondido por el user3496510 26.01.2017 - 13:15
fuente
0

Si necesita identificar de manera confiable la aplicación cliente (no el usuario, ni el dispositivo), entonces se está familiarizando con algunas de las técnicas utilizadas por DRM (Digital Rights Management). Ninguno de ellos es robusto, y es generalmente a través de la oscuridad. Así que estoy de acuerdo, si puede rearchitect para que no le importe qué aplicación lo está llamando, estará en una mejor posición.

    
respondido por el Sunil Agrawal 26.01.2017 - 00:03
fuente

Lea otras preguntas en las etiquetas