¿Por qué confiamos en la información de la sesión por el cable pero no en un token de acceso OAuth?

8

He pasado mucho tiempo estudiando la creación de una API que debe ser accesible mediante una aplicación de JavaScript de una sola página y cómo hacerla lo más segura posible.

Gran parte de lo que estoy leyendo sobre estándares como OAuth sugiere que nunca desea que el token de acceso que emite esté disponible directamente para el cliente, y es por eso que a menudo se critican cosas como la Subvención Implícita.

Recientemente leí este artículo: enlace

... que ofreció una interesante sugerencia de enviar solicitudes de proxy a la API a través de un componente del lado del servidor delgado, para que la aplicación de una sola página pueda autenticarse con el proxy, recuperar una cookie de sesión cifrada y luego realizar solicitudes al proxy servidor que adjuntaría el token de acceso del usuario a las solicitudes antes de reenviarlas a la API real.

Lo que me pregunto es ¿cómo es esto más seguro que simplemente entregarle al cliente un token de acceso? Si el atacante hubiera podido obtener el token de acceso, seguramente puede obtener la cookie que almacena la información de la sesión, que es tan buena como el token de acceso para realizar solicitudes a la API.

¿Por qué consideramos que las cookies cifradas con detalles de sesión en ellas son seguras, pero confiar en el cliente con el token de acceso real se considera inseguro?

La verdadera diferencia es que una API sin acceso directo del cliente se considera una API segura y privada, y cualquier API a la que deba acceder el cliente de alguna manera (incluso a través de un proxy) debe ser tratada como una API pública o abierta, y solo tiene que aceptar la compensación del riesgo de que alguien pueda falsificar solicitudes si pudiera obtener la cookie de sesión o el token de acceso.

¿Cuál es realmente la forma más segura para que una aplicación de una sola página demuestre su identidad con una API?

    
pregunta adam 09.12.2014 - 15:27
fuente

4 respuestas

5
  

Si el atacante hubiera podido obtener el token de acceso, seguramente puede obtener la cookie que almacena la información de la sesión

Un ataque XSS no puede acceder a la cookie si lo especifica con HttpOnly. Debe haber sido un descuido, él realmente debería haber mencionado esto. Ah, y Secure (solo HTTPS) también. Entonces esta cookie no puede ser robada a través de XSS o MitM'd / sniffed.

  

¿Por qué consideramos seguras las cookies cifradas con detalles de sesión en ellas,

Entonces, al colocar los tokens en una cookie marcada como HttpOnly, están a salvo de XSS. Al codificarlos, evitó que se filtraran, intencionalmente o no, por ejemplo, por el usuario que inspecciona sus cookies.

  

¿pero confiar en el cliente con el token de acceso real se considera inseguro?

Este problema no es realmente el cliente, sino un atacante XSS, que podría robar el access_token y luego hacerse pasar por el usuario.

Pero ahora que estamos usando cookies, su última declaración, hecha casi como una ocurrencia tardía, es importante:

  

Para proteger a un atacante que acaba de robar la cookie, puede utilizar medidas de protección CSRF.

Para mitigar CSRF, puede exigir en el servidor que el cliente proporcione un encabezado X-Requested-With (u otro personalizado). Eso evitará que los sitios maliciosos o los sitios pirateados con XSS llamen a sus API porque las restricciones de dominio cruzado del navegador no les permitirán agregar encabezados personalizados, y luego puede rechazar las solicitudes.

  

¿Cuál es realmente la forma más segura para que una aplicación de una sola página demuestre su identidad con una API?

He estado mirando a mi alrededor y creo que este enfoque, utilizando un servidor proxy, lo es. Encontrará variantes de él en otras partes buscando en Google, por ejemplo, aquí y aquí , pero el enfoque de Alex Bilbie de cifrar el access_token tiene una ventaja sobre los dos que nunca hay una ventana (incluso uno corto) donde access_token es vulnerable a XSS.

    
respondido por el Steve Kehlet 16.03.2015 - 20:44
fuente
2

El problema es que los tokens de acceso no están vinculados al cliente. Por lo tanto, no hay manera de saber si se emitió un token de acceso para su cliente o para otro cliente.

Básicamente, desde el punto de vista de OAuth 2.0, quien posea el token de acceso es USTED.

Escribí una gran respuesta explicando cómo esto es un problema. Aquí está el ataque que puedes montar:

  

Digamos que su servicio REST requiere un token de acceso de facebook.   Todo lo que un atacante debe hacer es alojar un servicio, por ejemplo   stackoverflow, y requiere un token de acceso desde facebook. Cuando tú   dar el token de acceso de Facebook a stackoverflow, stackoverflow (nuestro   el atacante) ahora puede hacerse pasar por tu servicio REST.

Todo eso porque los tokens de acceso no están vinculados a un cliente específico.

Puede parecer una locura que OAuth permita algo así, pero es cierto. OAuth simplemente asume que el riesgo es aceptable porque estaba destinado solo a la autorización y no a la autenticación. Y ese es el próximo gran problema. La mayoría de las personas no saben la diferencia entre la autorización y la autenticación y están haciendo un mal uso de OAuth a la izquierda y a la derecha.

Parte de la confusión proviene del hecho de que el flujo Authorization Code también proporciona autenticación como un efecto secundario ... Le sugiero que lea la siguiente sección en la especificación de OAuth:

  

¿Cuál es realmente la forma más segura para que una aplicación de una sola página   probar su identidad a una API?

Si quieres autenticación, usa OpenID. OpenID estaba destinado a la autenticación. OAuth es solo autorización.

OpenID se construye sobre OAuth y agrega todas las piezas faltantes que se requieren para proporcionar autenticación. Una de ellas es que, a diferencia de OAuth, OpenID vincula el token de acceso al cliente, por lo que el ataque mencionado anteriormente ya no funciona si está utilizando OpenID.

    
respondido por el Gudradain 06.01.2016 - 16:04
fuente
1

Creo que lo que él está tratando de decir es que no debes guardar todas las llaves en el mismo lugar. La compartimentación del proceso es lo que desempeña el papel clave en el mecanismo de autenticación que sugiere.

Una cosa que también debe tener en cuenta es aprovechar la Política del mismo origen . El uso de SOP evitará que los atacantes manipulen datos de un dominio que sea diferente al que tiene acceso (a menos que explote el navegador). Y no use WebSockets para manipular información confidencial, no están sujetos a esta política.

Hablando sobre el estándar actual (si eso es lo que quieres decir con "la forma más segura") de hacer esto, se lo daré a los desarrolladores aquí ...

    
respondido por el DarkLighting 09.12.2014 - 16:24
fuente
1
  

¿Por qué consideramos que las cookies cifradas con detalles de sesión en ellas son seguras, pero confiar en el cliente con el token de acceso real se considera inseguro?

Otro elemento clave del artículo de Alex Bilbie es que no puede realizar el cifrado en el cliente (en javascript) porque no puede mantener segura la clave de descifrado, lo que significa que cualquier persona puede obtener la clave y descifrarlo.

Al hacer la parte del servidor de cifrado, la clave secreta nunca se expone al cliente, que simplemente tiene un token 'opaco' para ofrecer a los servicios.

Aparte de esa adición, estoy completamente de acuerdo con Steve Kehlet.

    
respondido por el Alex White 06.01.2016 - 14:56
fuente

Lea otras preguntas en las etiquetas