Contraseña para borrar texto en HTML

7

¿Hay algún problema con la salida de la contraseña de un usuario al HTML en un campo oculto (vea el caso de uso a continuación antes de flamear xD)?

El caso de uso es un formulario de registro con dos pasos. El usuario completa la contraseña en el primer paso, pero para evitar almacenar los valores del campo en algún lugar del servidor, la aplicación envía los valores al cliente en el HTML como campos ocultos. Estos campos se vuelven a enviar al servidor cuando el cliente envía el segundo paso del registro. De esta manera, el servidor recibe todos los valores a la vez y la lógica es más sencilla.

Básicamente, esto simplemente divide la solicitud de registro en dos solicitudes, donde la segunda es la única que importa. El problema es que no estoy muy cómodo con tener la contraseña en el HTML, pero no puedo evocar una razón suficientemente buena para que esto esté mal ...

Editar

Para hacer las cosas un poco más difíciles, supongamos que HTTPS se usa en todas partes y que X-Frame-Options se usa para evitar el clickjacking. ¿Alguien puede pensar en algún ataque que no haya sido mencionado anteriormente que funcione con esta configuración?

    
pregunta Francisco Vieira 03.05.2013 - 19:49
fuente

6 respuestas

12

Veo algunas razones por las que no debo hacer eso:

  • El navegador del cliente puede (y probablemente lo hará) cachear la página HTML recibida en algún archivo en el disco local. Por lo general, no es una buena idea tener las contraseñas "como están" en los archivos del disco.

  • Dado que almacena datos en el lado del cliente (en el HTML), debe pensar qué sucede cuando el cliente no coopera, es decir, envía algo diferente a lo que su servidor escribió en el HTML. Dependiendo de su contexto, esto puede o no ser un problema, pero al menos debe pensarse debe al respecto.

La forma genérica y segura de hacer este tipo de cosas es enviar al cliente un blob encriptado, que contiene los datos del estado que desea almacenar en el cliente. El blob debe usar tanto el cifrado como un MAC para protegerse contra las alteraciones de clientes maliciosos. Donde realmente pones esa mancha no es muy importante; puede colocarlo en un campo oculto en el HTML, o en una cookie, realmente no importará ya que, a través del cifrado y el MAC, no confía en la máquina cliente para nada.

    
respondido por el Thomas Pornin 03.05.2013 - 19:58
fuente
4

Su caso de uso no es, en el contexto, diferente de volver a mostrar un formulario de una sola página que el usuario no completó correctamente, y por conveniencia su código de servidor rellenó los campos que el usuario llenó correctamente Vemos muchos ejemplos de este tipo en toda la web. La única diferencia es que utiliza dos páginas para un conjunto completo de datos de usuario requeridos (y opcionales) que está recopilando. También podría estar usando veinte de estos pasos, en realidad no importa desde la perspectiva de la seguridad (puede que también lo sean los usuarios, pero eso es un asunto diferente), siempre y cuando:

  • Te has ocupado de TLS
  • Usted trata todas las entradas de los usuarios, independientemente de la página de la que provengan, como un todo
  • No expone innecesariamente contraseñas de texto sin cifrar en el caché del usuario final

Usted mencionó en los comentarios que esto será en HTTPS, por lo que se cuida el primero. Los otros dos también son completamente manejables:

El código del lado del servidor que verifica la entrada del usuario tendrá que escribirse de tal manera que se adapte a múltiples páginas de formulario de usuario, pero también verifique las restricciones de entrada de manera incremental, lo que significa que cada página nueva verificará toda la entrada de datos en las anteriores. , hasta la página en la que el usuario está actualmente. También solo acepta todos estos formularios separados en su totalidad, lo que significa que una falla en uno vuelve a mostrar esa etapa de entrada del usuario final en particular, elimina todos los datos del formulario subsiguiente y muestra información relevante error para esa página (o etapa, paso, como quieras nombrarla). La parte importante es que usted acepta todos los comentarios del usuario solo una vez que todos los datos se verifican de acuerdo con sus requisitos en todas las etapas de ingreso de formularios. Solo entonces puede escribir cualquier cosa en su base de datos de forma segura, es decir, se cumplieron todos los requisitos.

¿Por qué el envío de contraseñas de usuario final en texto sin formato no es un problema? Porque ya lo has enviado al menos una vez en la otra dirección: al servidor. Si no se supone que eso sea un problema, enviarlo de vuelta con el mismo TLS no debería también. No debería , porque aún tendrá que considerar que los datos se almacenen en caché al final del usuario mediante el navegador, como lo señaló @ThomasPornin. Sin embargo, esto se puede controlar con las etiquetas de encabezado de la memoria caché del navegador, ya sea como etiquetas HTML o en los encabezados de respuesta del servidor HTTP. No voy a entrar en detalles sobre cómo lograrlo, ya que es un tema bien cubierto y también tiene muchos hilos en StackOverflow. La principal conclusión es que si su front-end ya estaba abierto por alguna inyección XSS, nada impide que esta inyección recopile datos del usuario final en el formulario enviado desde ese mismo campo de entrada, por lo que devolverlo no lo expone. más para estos tipos de ataques, pero aún se debe considerar la caché del cliente para evitar la exposición de contraseñas de texto sin cifrar a otros tipos de ataques.

Otros también han sugerido el uso de AJAX para partes de los datos de su formulario. Si bien es cierto que puede ayudar con las aportaciones del usuario, guiar a los usuarios sobre la marcha con retroalimentación, nunca debe aceptar solo datos parciales como algo en lo que confiar más adelante, al completar cualquiera de las dos etapas del envío del formulario o al completar El proceso en su conjunto. La verificación de la disponibilidad del nombre para mostrar, o similar, también está bien, pero si es en el tiempo que tarda otro usuario, seguramente no querrá confiar en la solicitud anterior de AJAX para decidir si el usuario actual aún puede usarla.

    
respondido por el TildalWave 06.05.2013 - 18:58
fuente
3

Si no desea almacenar la contraseña en el servidor, ¿por qué está haciendo dos pasos para la creación del usuario? Si solo está verificando la disponibilidad del nombre de usuario, ¿por qué no usa la devolución de datos de AJAX para enviar solo la información que necesita ser verificada y hacer todo de una forma?

Incluso si necesita devolverlo, no veo por qué no se puede mantener en la sesión del usuario siempre que el servidor nunca lo envíe de vuelta. Inmediatamente podría hacer el hash que se aplicará cuando lo almacene en la base de datos para que no se almacene nada que de lo contrario no estaría almacenando.

    
respondido por el AJ Henderson 03.05.2013 - 20:17
fuente
3

Al colocar la contraseña de texto no cifrado (o cualquier información confidencial) dentro del código fuente o el DOM de la página, está asumiendo un gran riesgo.

Por ejemplo, solo una simple vulnerabilidad de Secuencias de comandos entre sitios (XSS) hace que sea trivial leer ese valor y enviarlo a donde el atacante desee.

Además, se utilizan otras técnicas que involucran el clickjacking para leer contenido de fuentes iframe arbitrarias, como la que contiene su contraseña.

Almacenar datos confidenciales que no tienen por qué estar allí (es decir, el usuario no necesita para leerlos) dentro de la fuente de las páginas web nunca es bueno idea.

    
respondido por el Gurzo 04.05.2013 - 01:24
fuente
3

Si, por el motivo que sea, la contraseña necesita para ser devuelta y 'simplemente se queda ahí' en el segundo, ¿por qué no codificarla del lado del servidor con una cadena salt, es decir, myencode ($ salt, $ pass ); envíe el pase codificado hacia atrás y cuando se devuelva, decodifíquelo, es decir, mydecode ($ pass2); Esto parece ser la ruta más fácil que aún mantendría un nivel de seguridad decente.

O, un poco más complicado, pero para citar un póster anterior "esto grita ajax"

    
respondido por el Nisan 04.05.2013 - 04:45
fuente
2

Definitivamente un problema. Transmitir la contraseña en cualquier texto claro abre muchos problemas de seguridad.

Uno en particular que viene a la mente, ¿está seguro de que la red del usuario no está siendo detectada o escuchada? Al permitir la contraseña de texto sin cifrar (en general), cualquiera que pueda estar escuchando a escondidas la red del usuario no tendrá acceso completo a su contraseña. Esto crea otros problemas porque muchos usuarios usan la misma contraseña en varios sitios web. Acaba de permitir que su usuario se convierta en una víctima a través de una codificación deficiente.

Una nota al margen, ¿por qué no mover la parte de la contraseña a la segunda fase del registro y ser el último paso? De esa manera se transmite (con suerte) de manera cifrada y segura.

    
respondido por el Travis 03.05.2013 - 20:57
fuente

Lea otras preguntas en las etiquetas