javascript - localstorage - El uso de Stackoverflow del almacenamiento local para la Autorización parece inseguro. ¿Es esto correcto? ¿Cómo lo fortalecemos?
where store token (1)
Bueno, en lugar de mirar la vulnerabilidad, veamos los posibles vectores de ataque. Agregaré una tabla aquí como un TL / DR
Attacker | Vulnerable?
Eavesdropper | Yes
MITM | Yes
Local Attack | Yes
Server Attack | Yes
Entonces sí, es un problema.
Remote Attacker, puede observar el tráfico, pero no puede modificar el tráfico
Considere esto un atacante pasivo en una cafetería. Pueden ver todo el tráfico de nivel TCP.
Las solicitudes de ida y vuelta a SO están, por defecto, sin encriptar. Puede navegar a través de HTTPS, pero de manera predeterminada es solo HTTP.
Por lo tanto, un atacante puede ver cualquier solicitud pasar e inspeccionar / robar los datos.
Veamos si alguna vez se envía el token GlobalLogin
en una solicitud ...
De hecho, lo es. En la página de inicio de sesión, se envía una solicitud a través de un iframe a la siguiente URL:
https://stackauth.com/auth/global/read?request=//snip//
Esa URL devuelve un script:
var data = {
"ReadSession":"https://stackauth.com/auth/global/read-session",
"Request":"//snip//",
"Nonce":"//snip//",
"Referrer":"//snip//",
"StorageName":"GlobalLogin"
};
var toMsg = window.parent;
var obj = localStorage.getItem(data.StorageName);
if(obj != null) {
var req = new XMLHttpRequest();
req.open(
''POST'',
data.ReadSession+
''request=''+encodeURIComponent(data.Request)+
''&nonce=''+encodeURIComponent(data.Nonce)+
''&seriesAndToken=''+encodeURIComponent(obj),
false
);
req.send(null);
if(req.status == 200){
toMsg.postMessage(req.responseText, data.Referrer);
}else{
toMsg.postMessage(''No Session'', data.Referrer);
}
}else{
toMsg.postMessage(''No Local Storage'', data.Referrer);
}
Ahora, observe que GlobalLogin
se envía a través de HTTPS al servidor. Por lo tanto, un atacante remoto que pueda leer el tráfico no podrá obtener el token GlobalLogin
.
Entonces, la porción de GlobalLogin
está a salvo de los espías.
Sin embargo, tenga en cuenta que todavía es bastante vulnerable a oler la cookie de sesión, ya que se envía a través de HTTP.
Atacante remoto, puede modificar el tráfico (MITM)
Bueno, aquí es donde las cosas se ponen interesantes.
Si puede modificar el tráfico, puede hacer algo realmente divertido.
La página inicial crea un iframe que trae la URL de stackauth.com anterior a través de HTTPS. Bueno, si puede modificar la página inicial (también posible a través de XSS), puede degradar la solicitud a HTTP.
Y StackAuth.com estará bien con eso. Cuando realiza la solicitud a stackauth.com, debe interceptarlo también y cambiar su URL de ReadSession
para que también sea HTTP.
Pero, entonces, todo lo que tiene que hacer es mirar la llamada a la URL de ReadSession
, y boom, ha robado el token de GlobalLogin
.
Pero el tráfico es HTTP de todos modos, por lo que no importa, ya que no tiene que pasar por ese problema para robar la cookie. ¿Entonces, para qué molestarse?
Atacante local
Si la persona tiene acceso a la computadora para leer el archivo de almacenamiento local, pueden hacerlo mucho peor que solo robar su token de inicio de sesión.
Hay una clase de ataque llamado "Navegador en el medio", donde un compromiso en el navegador permite a un atacante hacer lo que quiera.
Y no hay una protección efectiva real contra ella que no sea para tratar de mantener el navegador seguro (no hay nada que pueda hacer desde su final).
Entonces, si un atacante puede obtener acceso local a la computadora, se acabó el juego.
Atacante basado en servidor
Si un atacante puede acceder a los servidores de StackOverflow, de todas maneras se acabó el juego ...
Conclusión
Mientras HTTP esté permitido (dado que un MITM siempre puede degradar la conexión a HTTP), no hay nada que proteger ya que los secretos de la sesión siempre pueden ser ocultados mediante escuchas ilegales.
La única forma de proteger esta información es usar HSTS y forzar HTTPS en todas partes.
Vale la pena señalar que puede proteger GlobalLogin
forzando HSTS en stackauth.com, dejando el sitio principal accesible a través de HTTP. Esto no evitaría el efecto del ataque (secuestro de sesión). Pero protegería el único vector.
Pero pasar HTTPS solo a través de HSTS en todas partes sería la mejor y única forma de prevenir este tipo de problemas. Cualquier otra cosa sería una tirita en una herida de bala.
Nota: Hice una conversación con SO sobre esto antes de publicar esto.
He estado trabajando en un módulo de Autenticación y autorización similar a cómo stackexchange está en su lugar. Ahora estoy seguro de que usan cierto modelo de oAuth o un servidor de generación de tokens que autoriza el uso de sus diversos sitios. Intenté un pequeño experimento.
Una vez que inicie sesión en Stackoverflow, borro todas mis cookies de la consola de desarrollador.
Dejo mi objeto localstorage intacto que contiene una clave se:fkey xxxxxxxxxxxxxxxxxxxxxxxxx
para el dominio stackoverflow.
hay otra clave para el dominio stackauth GlobalLogin: xxxxxxxxxxxxxxxxxxxxxxx
the se.fkey si utilicé un secuestro de sesión, no pasó nada. pero GlobalLogin, pude copiar y secuestrar mi sesión. Por lo tanto, mi consulta sería, ¿cómo se trata S / O con la autenticación de la autorización de publicación para cada uno de los sitios. Además, ¿hay alguna manera de invalidar la GlobalLogin para ellos después de que se utiliza una vez?
{EDIT1}
Entonces, solo el globalLogin
solo es suficiente. Si puede obtener esa clave, simplemente abra una instancia de navegación privada. En Localstorage para stackauth cuando esté en la página de inicio de sesión, cree la asignación de key-value
y actualice la página. Usted habrá iniciado sesión.
{EDIT2}
La clave globalLogin
parece ser coherente en varias sesiones. Ha pasado un día sin actualización de mi clave globalLogin
. Es seguro suponer que si su clave es secuestrada, el atacante tendrá acceso a su perfil indefinidamente.
{EDIT3}
Para todos los que voten, votarán esta pregunta como una pregunta no relacionada con la programación. Permítanme decirlo de esta manera, ¿cómo almacenamos los SSO en el navegador web con el almacenamiento local de forma segura y como son propensos a comprometerse, qué debemos hacer para evitar que suceda? Uno de mis colegas fue lo suficientemente considerado como para darme su clave GlobalLogin, pude secuestrar su sesión desde otra computadora, aunque estaba en la misma red.
PD: Esto es puramente para la comprensión teórica de que hice esto.