¿Cómo aseguro mi API REST?

80

En detalle, aquí está el problema:

Estoy creando una aplicación para Android, que consume mi API REST en el back-end. Necesito crear una API de registro e inicio de sesión para empezar. Después de buscar con Google por un tiempo, siento que solo hay dos enfoques que puedo tomar.

  • Durante el registro, uso enlace y obtengo las credenciales del usuario; guárdelo en mi base de datos contra el nombre de usuario (lado del servidor). Durante el inicio de sesión, otra vez uso enlace y pido las credenciales del usuario; verifique la contraseña con hash en la base de datos y devuélvale un ID de sesión, que planeo no caducar nunca a menos que cierre la sesión. Además, cualquier otra llamada a la API (GET / POST) que realice el usuario, se acompañará con este ID de sesión para que pueda verificar al usuario.

Pero en el enfoque anterior, estoy obligado a usar enlace para cualquier llamada a la API, de lo contrario, soy vulnerable a Man in The Middle Attack , es decir, si alguien huele mi ID de sesión, puede reconstruir las solicitudes GET / POST similares que no quisiera. ¿Tengo razón con la suposición anterior?

  • La segunda opción es seguir la ruta de Amazon Web Services , donde uso la autenticación de clave pública / privada. Cuando un usuario se registra, utilizo una API enlace para guardar sus credenciales en la base de datos. A partir de entonces, uso la contraseña del usuario como clave privada. Cualquier otra llamada a la API que el usuario haga tendrá un bloc con hash de la URL de solicitud utilizando la clave privada del usuario. En el lado del servidor, reconstruyo el hash usando la clave privada guardada. Si el hash es una coincidencia, dejo que el usuario haga su tarea; En esta opción, necesito usar enlace solo para la API de registro. El REST puede continuar en enlace .

Pero aquí la desventaja es que me veo obligado a alojar mi API de registro en un directorio virtual separado (estoy usando IIS y no estoy seguro de poder alojar las API http y https en el mismo directorio virtual ). Por lo tanto, me veo obligado a desarrollar la API de registro en un archivo de proyecto separado. De nuevo, ¿estoy en lo cierto con el supuesto anterior?

Editar: Estoy usando ASP.NET MVC4 para crear la API web.

La razón por la que me resisto a usar enlace para todas mis llamadas a la API REST es que siento que no es liviano y crea más carga útil de la red, lo que puede no serlo. más adecuado para una aplicación móvil. Más cifrado / descifrado y un saludo adicional requerido pueden afectar aún más la duración de la batería de un móvil. ¿O no es significativo?

¿Cuál de los dos enfoques anteriores sugeriría?

PS: Fuimos con Https a todas partes, y fue la mejor decisión. Más de eso en mi blog .

    
pregunta noob Mama 09.09.2012 - 10:01
fuente

6 respuestas

50

Iría con SSL / TLS en todas partes (ya que controlas ambos lados, obligar a TLS 1.2 debería ser factible). Es relativamente fácil de usar y obtienes muchas funciones de seguridad de forma gratuita. Por ejemplo, si no usa SSL, deberá preocuparse por los ataques de reproducción.

Si le preocupa el rendimiento, asegúrese de que la reanudación de la sesión sea compatible con el servidor y el cliente. Esto hace que los apretones de manos posteriores sean mucho más baratos. Dado que el protocolo de enlace es bastante caro en SSL en comparación con el cifrado de los datos reales, esto reduce considerablemente la carga general.

Si usa HTTP 2, incluso puede enviar varias solicitudes a través de una sola conexión, de esa forma evitará la sobrecarga de reconocimiento TCP y SSL completa en solicitudes posteriores.

    
respondido por el CodesInChaos 09.09.2012 - 12:25
fuente
23

Recomiendo usar OAuth. Definitivamente deberías leerlo si no estás familiarizado con él. Como ventaja adicional, puede utilizar proveedores de identidad de terceros, para que sus usuarios puedan usar sus cuentas de Google / Windows Live / etc. para su aplicación, lo que evita el registro.

Incluso si desea rodar su propio marco de autenticación, no recomiendo usar sesiones que no expiren. La sesión debe expirar después de un tiempo de inactividad suficiente, de lo contrario, esto da más espacio para la explotación (por ejemplo, secuestro de sesión).

    
respondido por el Zsombor Erdődy-Nagy 09.09.2012 - 10:38
fuente
3

Depende de qué tan seguro necesita ser. Cada vez que hace que la solución sea más compleja, también es probable que deje un gran vacío . No se pretende ofender aquí, pero supongo que no es un experto en seguridad, debido al hecho de que está haciendo la pregunta. Es mejor utilizar algún tipo de módulo de autenticación y autenticación estándar de la industria.

Probablemente estarás bien, siempre y cuando estés:

  • cifrar la contraseña (con algo como AES o Blowfish)
  • enviando la contraseña
  • enviar los datos a través de HTTPS

Una alternativa es OAuth.

Si alguien quiere hackearte lo suficiente, siempre encontrarán la manera. El secreto es aumentar el tiempo y el esfuerzo necesarios para que no valga la pena que alguien lo haga. Por lo tanto, si no tiene grandes cantidades de datos de clientes y / o financieros, y no es una empresa de alto perfil, una implementación de seguridad estándar como la anterior debería estar bien.

    
respondido por el Dan Blows 09.09.2012 - 10:19
fuente
2

En JEE tenemos la noción de seguridad administrada por contenedor. En cuyo caso, configuro mis servicios de descanso para usar la autenticación básica, que de forma predeterminada utiliza la autenticación de contraseña HTTP en un entorno configurado en el servidor de aplicaciones. Esto evita la necesidad de un formulario HTML para iniciar sesión, o la complejidad de implementar certificados del lado del cliente.

La aplicación simplemente asume que habría un principal de usuario y tal vez otros datos, como los detalles de identificación que se pasan con la solicitud. Esto incluye las APIs descansadas.

En mi configuración, implementé un OAuth2 JASPIC server auth module [ Source ] que almacena el token de OAuth que está cifrado simétricamente donde la clave reside en el servidor que también tiene un vida limitada en cookie y usar eso como la autenticación para la aplicación.

Al hacer lo anterior, mantengo la aplicación alejada de la semántica de autenticación y como beneficio adicional cuando quiero realizar pruebas de integración funcional utilizando Selenium, puedo degradar el uso de contraseñas HTTP en lugar de tener una prueba compleja que se conecte a un proveedor de OAuth todo el tiempo.

Además, seguiré usando SSL para garantizar que al menos su transporte sea seguro. No usar SSL solo agrega demasiada complejidad al tratar con ataques comunes a su aplicación.

Tenga en cuenta que esto es JEE, pero los mecanismos se pueden aplicar a cualquier tecnología.

    
respondido por el Archimedes Trajano 08.07.2014 - 08:15
fuente
2

Nunca estarás 100% seguro de que tu API sea segura.

La razón principal de esto es que probablemente esté entregando un binario a sus clientes / usuarios que simplemente funciona. Entonces, tienen todo el tiempo del mundo para analizar ese binario y buscar claves / secretos en él, que se utilizan para autenticarse de forma segura en su servidor de API. El punto final de la API del cliente es el punto más débil, ya que son propietarios del dispositivo en el que se ejecuta el binario, por lo tanto, pueden manipular los certificados que su dispositivo considera válidos o no.

Un claro ejemplo de lo que estoy hablando es este artículo ("Un tutorial para la ingeniería inversa de la API privada de su software: hackear su sofá"). Y me gustaría finalizar esta respuesta citando uno de los últimos párrafos:

  

¿Es posible evitar completamente el uso de una API privada por   clientes de terceros? No lo creo. El uso de la fijación de SSL evitaría   rastrear las solicitudes de API usando una técnica simple de proxy transparente   como se describió anteriormente. Al final, incluso si ofuscas el binario, un   hacker motivado con algunos recursos y tiempo siempre será capaz de   Realice una ingeniería inversa del binario de la aplicación y obtenga la clave / certificado privado. yo   Creo que la suposición de que el punto final del cliente es seguro es inherentemente   incorrecto. Un cliente API es un punto débil.

    
respondido por el knocte 02.07.2016 - 10:13
fuente
1

Sólo HTTPS es una necesidad.

Al controlar tanto la aplicación como la api, implementaría la fijación de certificados. La fijación de certificados puede ser derrotada, pero es un buen elemento de disuasión contra el inspector ocasional.

Puede agregar otra capa con cifrado de carga útil. Eso viene a costa de la construcción de un sólido proceso de distribución de claves y rotación de claves.

Si su aplicación usa tokens de acceso o cookies de sesión para autorizar a API específicas, asegúrese de que expiren. Muy a menudo observo tokens que no caducan por días, meses o alguna vez.

Regla de oro: Un O / S móvil es un entorno hostil. Trátela con cuidado y amp; una falta de confianza

    
respondido por el rustyMagnet 18.07.2016 - 15:16
fuente

Lea otras preguntas en las etiquetas