Asegurando la API REST sin HTTPS

4

Estoy desarrollando una API REST pero no puedo usar HTTPS sin usar certificados autofirmados . Entiendo que eso podría ser aceptable para algunos, pero no quiero que aparezcan mensajes de seguridad en los navegadores de los clientes.

La información que se pasa a la red no es confidencial, por lo que no me importa la escucha, pero quiero asegurarme de que solo los clientes autorizados puedan realizar solicitudes y evitar los ataques de repetición. Aquí está mi idea:

Un usuario está registrado con la aplicación web que ejecuta el servicio. Quieren registrar un cliente API, pero no son desarrolladores, por lo que descargan una aplicación cliente suministrada (en este caso, un lector de tarjetas IC que usarán con una computadora que puede comunicar los datos leídos de las tarjetas escaneadas al servicio web). sobre la API).

Paso uno : la aplicación cliente API genera un par de claves (por ejemplo, OpenSSL) y envía la clave pública al servidor (esto puede ser un paso de carga manual cuando el usuario registra al cliente con el servidor ). El servidor almacena la clave pública en la base de datos asociada con el usuario y una descripción del cliente (por ejemplo, "Lector de tarjetas IC en PC01").

¿Por qué quiero usar un par de claves (como SSH)? Creo que un secreto compartido es vulnerable a las escuchas ilegales, ya que debe ser transferido a través de la red al menos una vez. Si bien esto podría evitarse ingresando manualmente la clave en el terminal del servidor en lugar de transportarla a través de la red, uno de los objetivos de diseño del sistema es permitir que otros usuarios que no sean yo mismo registren clientes y obtengan un token de acceso API mediante la interfaz web solicitud. En esta circunstancia, un intruso podría interceptar una clave secreta compartida, mientras que un par de llaves generado por el cliente lo evitaría.

Paso dos : al realizar una solicitud, el cliente primero obtiene un nonce del servidor (que lo almacena en una lista o base de datos de nonces y marcas de tiempo emitidas) y luego realiza la solicitud incluyendo el nonce mientras Firmando la solicitud con su clave privada. El servidor verifica que el mensaje es auténtico (fue firmado por el cliente y nadie más) antes de ejecutar la solicitud.

Mi objetivo con este enfoque es garantizar que solo los clientes válidos accedan a la API, al mismo tiempo que evitan los ataques de reproducción. Un atacante debe poder ver el contenido de los mensajes (no es realmente sensible), pero no debe poder modificarlos. Al cliente realmente no le importa si los datos que vienen del servidor son auténticos (porque en este caso el cliente está cambiando el estado del servidor, no al revés).

  • ¿Este enfoque cumple con estos objetivos de diseño?
  • Y lo previene contra los ataques del hombre en el medio (asumiendo el original El registro del cliente fue con el servidor real y no un falso del atacante)?
pregunta Aaron D 11.07.2015 - 15:31
fuente

4 respuestas

2

Tenga en cuenta que HTTPS (sin autenticación de cliente) en realidad no le ayudará a lograr su objetivo de:

  

Mi objetivo con este enfoque es garantizar que solo los clientes válidos sean   acceder a la API, al mismo tiempo que evita los ataques de reproducción.

HTTPS (sin autenticación de cliente) evitará que sus clientes hablen con alguien que se haga pasar por su servidor; no evitará que alguien que se haga pasar por clientes se comunique con un servidor real.

Por lo tanto, incluso si logra obtener un certificado TLS adecuado, tendrá que aplicar algunas medidas de seguridad para lograr los objetivos establecidos.

  

¿Este enfoque cumple con estos objetivos de diseño?

Yo diría que sí, siempre que:

  • el servidor aplica correctamente la singularidad de nonce y evita la reutilización de nonce;
  • el cliente incluye ese nonce en respuesta y firma la respuesta completa , incluyendo URI, encabezados, carga útil.

Puedes usar firmas asimétricas (como propones) o simétricas (por ejemplo, HMAC). Ambos enfoques deberían funcionar siempre que pueda garantizar que el intercambio inicial (clave pública o carga secreta compartida) se realice a través de un canal seguro. Amazon prefiere HMAC y esta biblioteca admite RSA, DSA y HMAC.

  

¿Y previene contra ataques de hombre en el medio (asumiendo que   El registro original del cliente fue con el servidor real y no   el falso de un atacante)?

Depende. El atacante aún puede suplantar al servidor y enviar datos maliciosos al cliente (porque el cliente no autentica al servidor de ninguna manera, esta es la parte en la que HTTP podría ayudar).

Al mismo tiempo, si puede garantizar que el intercambio inicial de datos de autenticación (clave pública en caso de RSA o secreto compartido en caso de HMAC) se realizó a través de un canal seguro, entonces el servidor debería poder detectar y rechazar cualquier manipulación indebida. Respuestas (es decir, con un nonce o firma no válidos) y esto proporciona una autenticación de cliente que es resistente a MITM.

Esta parte debe evaluarse con mucho cuidado con respecto a los flujos de protocolo (quién inicia la solicitud, qué son los flujos de datos, etc.) porque el cliente no tiene medios para autenticar el servidor.

    
respondido por el Andrey 13.07.2015 - 00:18
fuente
4
  

Mi objetivo con este enfoque es garantizar que solo los clientes válidos accedan a la API, al mismo tiempo que evitan los ataques de reproducción.

Use un valor nonce cada vez mayor.

  

Un atacante debe poder ver el contenido de los mensajes (no es realmente sensible), pero no debe poder modificarlos.

Tener una clave API y un secreto.

Sus solicitudes contienen la clave en texto simple.

También incluyen un valor 'hash'. Este valor de hash es un hash (por ejemplo, sha256) de la concatenación del secreto de API, su valor de nonce cada vez mayor y los datos de la solicitud en sí. El servidor genera su propio hash y lo compara con el que envió su cliente.

Un atacante puede leer su solicitud de API, pero como no tiene su secreto de API, no podrá crear un nuevo valor de "hash" y enviar sus propios datos arbitrarios. Tampoco podrá reproducir llamadas API antiguas debido a su valor de nonce.

    
respondido por el ieatpizza 11.07.2015 - 18:04
fuente
1

No, no impide un ataque MITM. No puede tener autenticación del cliente sin autenticación del servidor. La razón por la que el cliente tiene la garantía es que incluso está hablando con su servidor y su servidor no tiene seguridad de que realmente esté hablando con el cliente.

Sin autenticar el servidor esto:

Cliente < -------- > Servidor

es idéntico a esto:

Cliente < ----- > MITM < -------- > Servidor

El MITM puede modificar cualquier cosa enviada desde el servidor al cliente o desde el cliente al servidor. El cliente solo ve lo que el MITM quiere que vea y las únicas solicitudes que lo hacen al servidor son las permitidas por el MITM.

En su ejemplo, el cliente solicita un nonce, el servidor envía un nonce (MITM hace una copia). El cliente crea una solicitud, MITM la intercepta y la modifica a lo que quiera y la transmite al servidor. El servidor cree que la solicitud es auténtica.

Ahora se puede usar el certificado autofirmado "si" tiene algún método para proporcionar la identificación (huella digital o clave pública) al cliente mediante la comunicación fuera de banda. De esta manera, el cliente puede establecer de forma segura un canal de comunicación cifrado y autenticado con el servidor asegurándose de que el servidor hola (parte del protocolo de enlace SSL) coincida con el "Id" compartido previamente del certificado de servidor esperado.

Esto puede funcionar en su escenario, pero en la mayoría de los escenarios conduce a una situación de gallina y huevo. La comunicación es segura SI puedo obtener de forma segura la identificación válida del certificado del servidor para el cliente, pero para eso necesito algún tipo de comunicación segura. El punto de CA es arrancar ese proceso.

    
respondido por el Gerald Davis 12.07.2015 - 19:16
fuente
0

No tengo idea de por qué el OP no puede permitir el acceso de puerto a 443, sino a 80. En ese caso, simplemente puede establecer una regla de entrada para cualquier puerto que sea compatible con HTTPS (cualquier TCP / IP es ..). Solo establece el puerto configurado y configura un HTTPS.

También, para las API, hay un conjunto completo de seguridad de API en OWASP que puede consultar. Aquí hay una hoja de trucos que puedes defender:

https://www.owasp.org/index.php/REST_Security_Cheat_Sheet

También puede optar por implementar una buena medida de seguridad ya hecha implementando esto:

https://www.owasp.org/index.php/ESAPI_Secure_Coding_Guideline

Todas las guías son mantenidas por la comunidad OWASP. No estoy seguro si sus certificados TLS tienen problemas con su configuración, en caso de que así sea, contacte a su proveedor para este soporte.

    
respondido por el Shritam Bhowmick 12.07.2015 - 18:59
fuente

Lea otras preguntas en las etiquetas