security - ¿Son las preocupaciones de seguridad el envío de una contraseña con una solicitud GET a través de https válida?
authentication ssl (4)
Tenemos una página web que usa el marco sapui5 para construir un spa . La comunicación entre el navegador y el servidor utiliza https . La interacción para iniciar sesión en la página es la siguiente:
- El usuario abre el sitio web ingresando
https://myserver.com
en el navegador - Se muestra un diálogo de inicio de sesión con dos campos de formulario para el nombre de usuario y la contraseña.
- Después de ingresar el
username
ypassword
y presionar ellogin-button
- se envía una solicitud ajax utilizando
GET
a la URL:https://myusername:[email protected]/foo/bar/metadata
Según mi entendimiento, usar GET para enviar datos confidenciales nunca es una buena idea. Pero esta respuesta a HTTPS es la cadena de url segura dice lo siguiente
HTTPS Establishes an underlying SSL conenction before any HTTP data is
transferred. This ensures that all URL data (with the exception of
hostname, which is used to establish the connection) is carried solely
within this encrypted connection and is protected from
man-in-the-middle attacks in the same way that any HTTPS data is.
Y en otra respuesta en el mismo hilo:
These fields [for example form field, query strings] are stripped off
of the URL when creating the routing information in the https packaging
process by the browser and are included in the encrypted data block.
The page data (form, text, and query string) are passed in the
encrypted block after the encryption methods are determined and the
handshake completes.
Pero parece que todavía puede haber problemas de seguridad al usar get :
- La URL se almacena en los registros en el servidor y en el mismo hilo
- fuga a través del historial del navegador
¿Es este el caso de las URL como?
https://myusername:[email protected]/foo/bar/metadata
// or
https://myserver.com/?user=myUsername&pass=MyPasswort
Preguntas adicionales sobre este tema:
- Está pasando las variables get sobre ssl seguras
- Está enviando una contraseña en json sobre https considerada segura
- ¿Cómo enviar contraseñas de forma segura a través de GET / POST?
En security.stackexchange hay informaciones adicionales:
Pero en mi opinión algunos aspectos todavía no están respondidos.
Pregunta
En mi opinión, los puntos mencionados son objeciones válidas para no usar get. Es el caso; ¿Usar get para enviar contraseñas es una mala idea?
¿Son estas las opciones de ataque, hay más?
- historial del navegador
- registros del servidor (asumiendo que la url está almacenada en los registros sin cifrar o encriptados)
- Información de referencia (si este es realmente el caso)
¿Qué opciones de ataque existen cuando se envían datos confidenciales (contraseña) a través de https usando get?
Gracias
El envío de cualquier tipo de datos confidenciales a través de GET es peligroso, incluso si es HTTPS. Estos datos pueden terminar en archivos de registro en el servidor y se incluirán en el encabezado del Referer en los enlaces o en las partes desde otros lados. También se guardarán en el historial del navegador para que un atacante intente adivinar y verificar el contenido original del enlace con un ataque contra el historial.
Aparte de eso, es mejor que hagas ese tipo de preguntas en security.stackexchange.com.
Estos dos enfoques son fundamentalmente diferentes:
-
https://myusername:[email protected]/foo/bar/metadata
-
https://myserver.com/?user=myUsername&pass=MyPasswort
myusername:myPassword@
es la "Información del usuario" (este formulario está en desuso en el último URI RFC), mientras que ?user=myUsername&pass=MyPasswort
es parte de la consulta.
Si nos fijamos en este ejemplo de RFC 3986:
foo://example.com:8042/over/there?name=ferret#nose
/_/ /______________//_________/ /_________/ /__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ / / /
urn:example:animal:ferret:nose
myusername:myPassword@
es parte de la autoridad . En la práctica, el uso de encabezados de autenticación HTTP (Básico) generalmente se utilizará para transmitir esta información. En el lado del servidor, los encabezados generalmente no se registran (y si lo están, si el cliente los ingresó en su barra de ubicación o mediante un cuadro de diálogo de entrada no haría ninguna diferencia). En general (aunque depende de la implementación), los navegadores no lo almacenan en la barra de ubicación, o al menos eliminan la contraseña. Parece que Firefox mantiene la información del usuario en el historial del navegador, mientras que Chrome no (y IE no los admite sin solución )
En contraste ?user=myUsername&pass=MyPasswort
es la consulta , una parte mucho más integral del URI, y se envía como el URI de solicitud HTTP . Esto estará en el historial del navegador y en los registros del servidor. Esto también se pasará en el referente.
En pocas palabras, myusername:myPassword@
está claramente diseñado para transmitir información que es potencialmente confidencial, y los navegadores generalmente están diseñados para manejar esto adecuadamente, mientras que los navegadores no pueden adivinar qué parte de qué consultas son sensibles y cuáles no: esperar información fugas allí.
Por lo general, la información del remitente tampoco se filtrará a terceros, ya que el encabezado del remitente proveniente de una página HTTPS normalmente solo se envía con otra solicitud de HTTPS al mismo host. (Por supuesto, si ha usado https://myserver.com/?user=myUsername&pass=MyPasswort
, esto estará en los registros de ese mismo host, pero no lo está haciendo muy valioso ya que permanece en el mismo servidor registros.)
Esto se especifica en la especificación HTTP (Sección 15.1.3) :
Los clientes NO DEBEN incluir un campo de encabezado de referencia en una solicitud HTTP (no segura) si la página de referencia se transfirió con un protocolo seguro.
Aunque es solo un "NO DEBE", Internet Explorer, Chrome y Firefox parecen implementarlo de esta manera. Si esto se aplica a las solicitudes HTTPS de un host a otro depende del navegador y su versión.
Ahora es posible anular este comportamiento, como se describe en esta pregunta y este borrador de especificación , usando un encabezado <meta>
, pero no lo haría en una página sensible que use ?user=myUsername&pass=MyPasswort
todos modos.
Tenga en cuenta que el resto de la especificación HTTP (Sección 15.1.3) también es relevante:
Los autores de servicios que utilizan el protocolo HTTP NO DEBEN utilizar formularios basados en GET para el envío de datos confidenciales, ya que esto hará que estos datos se codifiquen en el URI de la solicitud. Muchos servidores, servidores proxy y agentes de usuario existentes registrarán el URI de la solicitud en algún lugar donde pueda ser visible para terceros. Los servidores pueden utilizar el envío de formularios basado en POST en su lugar
El uso de ?user=myUsername&pass=MyPasswort
es exactamente como usar un formulario basado en GET y, aunque el problema del Referer puede contenerse, los problemas relacionados con los registros y el historial permanecen.
La comunidad ha proporcionado una visión amplia sobre las consideraciones, lo anterior se mantiene con respecto a la pregunta. Sin embargo, las solicitudes GET pueden, en general, necesitar autenticación. Como se observó anteriormente, enviar el nombre de usuario / contraseña como parte de la URL nunca es correcto, sin embargo, esa no suele ser la forma en que generalmente se maneja la información de autenticación. Cuando se envía una solicitud de un recurso al servidor, el servidor generalmente responde con un encabezado 401 y Autenticación en la respuesta, contra el cual el cliente envía un encabezado de Autorización con la información de autenticación (en el esquema Básico). Ahora, esta segunda solicitud del cliente puede ser una solicitud POST o GET, nada lo impide. Por lo tanto, en general, no es el tipo de solicitud, sino el modo de comunicar la información en cuestión.
Consulte http://en.wikipedia.org/wiki/Basic_access_authentication
Supongamos que el usuario hizo clic en un botón y sigue la solicitud generada por el navegador del cliente.
https://www.site.com/?username=alice&password=b0b123 !
HTTPS
Primero lo primero. HTTPS no está relacionado con este tema. Porque el uso de POST o GET no importa desde la perspectiva del atacante. Los atacantes pueden obtener fácilmente datos confidenciales de la cadena de consulta o directamente del cuerpo de la solicitud POST cuando el tráfico es HTTP. Por eso no hace ninguna diferencia.
Registros del servidor
Sabemos que Apache, Nginx u otros servicios registran cada solicitud HTTP en el archivo de registro. Lo que significa que la cadena de consulta (? Username = alice & password = b0b123!) Se escribirá en los archivos de registro. Esto puede ser peligroso debido a que el administrador del sistema también puede acceder a estos datos y obtener todas las credenciales de los usuarios. También podría ocurrir otro caso cuando el servidor de su aplicación se comprometa. Creo que estás almacenando la contraseña como hash. Si utiliza un potente algoritmo de hash como SHA256, la contraseña de su cliente será más segura contra los piratas informáticos. Pero los piratas informáticos pueden acceder a los archivos de registro directamente a través de contraseñas como texto sin formato con scripts de shell muy básicos.
Información del Referente
Asumimos que el cliente se abrió por encima del enlace. Cuando el navegador del cliente obtenga contenido html e intente analizarlo, verá la etiqueta de imagen. Estas imágenes se pueden alojar fuera de su dominio (postimage o servicios similares, o directamente un dominio que está bajo el control del pirata informático). El navegador realiza una solicitud HTTP para obtener la imagen. ¡Pero la url actual es https://www.site.com/?username=alice&password=b0b123 ! que va a ser información de referencia!
Eso significa que alice y su contraseña se pasarán a otro dominio y se puede acceder directamente desde los registros web. Este es un problema de seguridad realmente importante.
Este tema me recuerda a las vulnerabilidades de fijación de sesión. Lea el siguiente artículo de OWASP para ver casi la misma falla de seguridad con las sesiones. ( https://www.owasp.org/index.php/Session_fixation ) Vale la pena leerlo.