Mi servicio REST actualmente usa la autenticación SCRAM para emitir tokens para llamantes y usuarios.
Los tokens emitidos por el intercambio SCRAM tienen un tiempo de caducidad después del cual se requiere un inicio de sesión repetido. También emitiremos tokens 'infinitos' que no tienen vencimiento para simplificar la integración para las personas (que usarán nuestro servicio para uso personal) y en preparación para un punto final de JSONP.
Tenemos la capacidad de revocar los privilegios de las personas que llaman (la cuenta a la que se adjunta el token) y prohibir las IP, así como imponer cuotas a cualquier tipo de solicitud en cualquier período de tiempo.
Una cosa que no he implementado, sin embargo, es MAC para solicitudes. A medida que lo he pensado más, para algunas solicitudes creo que es necesario, ya que de lo contrario se pueden robar tokens y antes de identificar esto y desactivar la cuenta de la persona que llama asociada, se podrían causar daños a nuestras cuentas de usuario.
En muchos sistemas, el MAC se genera desde el cuerpo o la cadena de consulta de la solicitud, sin embargo, esto es difícil de implementar ya que estoy usando la API web de ASP.Net y no quiero leer el cuerpo dos veces. Igualmente importante, quiero que sea sencillo para que las personas que llaman puedan acceder al servicio, y tengo que ser capaz de admitir tanto aplicaciones de escritorio / móviles como navegadores web.
Entonces, lo que estoy pensando es tener una clave MAC enviada a un usuario en el registro, y hacer que calculen una solicitud MAC en:
- la url, posiblemente menos una cadena de consulta
- el verbo
- la IP de la solicitud (aunque potencialmente es una barrera en algunos dispositivos móviles y definitivamente está en javascript)
- utc fecha y hora en que el cliente emite la solicitud.
Por supuesto, el cliente enviaría esa cadena en el encabezado de una solicitud, por supuesto, y puedo usarla para decidir si la solicitud es lo suficientemente "nueva".
Mi idea es que, si bien esto no evita la manipulación del mensaje, sí evita el uso de una solicitud modelo para usarla como plantilla para diferentes solicitudes posteriores por parte de un tercero malintencionado. Creo que solo el hombre más agresivo en el ataque central podría subvertir esto, y no creo que nuestros servicios ofrezcan ninguna información o habilidad que sea lo suficientemente valiosa como para justificar eso.
Los servicios también usarán SSL, para cosas sensibles. Y si hago esto, entonces estaré usando HMAC-SHA-256 con la clave generada usando un PRNG.
¿Esto suena lo suficiente? ¿Me he perdido algo?
No creo que sea un principiante cuando se trata de seguridad, pero cuando trabajo en ello siempre lo hago. Estoy envuelto en dudas, ¡así que aprecio tener esta comunidad a la que llamar!