Estoy obligado a desarrollar una aplicación web que funcione sin conexión durante largos períodos. Para que esto sea viable, no puedo evitar guardar datos confidenciales (datos personales pero no el tipo de datos que solo almacenaría hash) en el almacenamiento local.
Acepto que esto no es una práctica recomendada, pero con pocas opciones, estoy haciendo lo siguiente para proteger los datos:
- cifrando todo lo que va al almacenamiento local utilizando la biblioteca criptográfica de JavaScript de Stanford y AES-256
- la contraseña del usuario es la clave de cifrado y no está almacenada en el dispositivo
- sirviendo todo el contenido (cuando está en línea) desde un único servidor confiable a través de SSL
- validando todos los datos que van y vienen del almacenamiento local en el servidor usando el proyecto owasp antisamy
- en la sección de red de appcache, sin usar *, y en su lugar enumerando solo los URI necesarios para la conexión con el servidor de confianza
- en general tratando de aplicar las pautas sugeridas en la hoja de trucos OWASP XSS
Aprecio que el diablo a menudo está en los detalles, y sé que hay mucho escepticismo sobre el almacenamiento local y la seguridad basada en JavaScript en general. ¿Alguien puede comentar si hay:
- defectos fundamentales en el enfoque anterior?
- ¿Alguna solución posible para tales defectos?
- ¿Alguna mejor manera de asegurar el almacenamiento local cuando una aplicación html 5 debe funcionar sin conexión durante largos períodos?
Gracias por cualquier ayuda.
html
security
local-storage
html5-appcache
owasp
usuario1173706
fuente
fuente
Respuestas:
WebCrypto
Las preocupaciones con la criptografía en JavaScript del lado del cliente (navegador) se detallan a continuación. Todas menos una de estas preocupaciones no se aplican a la API de WebCrypto , que ahora es razonablemente compatible .
Para una aplicación sin conexión, aún debe diseñar e implementar un almacén de claves seguro.
Aparte: si está utilizando Node.js, use la API de cifrado incorporada .
Criptografía Native-Javascript (pre-WebCrypto)
Supongo que la principal preocupación es alguien con acceso físico a la computadora que lee
localStorage
su sitio y desea criptografía para evitar ese acceso.Si alguien tiene acceso físico, también está abierto a otros ataques y algo peor que leer. Estos incluyen (pero no se limitan a): registradores de teclas, modificación de script fuera de línea, inyección de script local, envenenamiento de caché del navegador y redireccionamientos de DNS. Esos ataques solo funcionan si el usuario usa la máquina después de haber sido comprometida. Sin embargo, el acceso físico en tal escenario significa que tiene mayores problemas.
Tenga en cuenta que el escenario limitado en el que la criptografía local es valiosa sería si se roba la máquina.
Hay bibliotecas que implementan la funcionalidad deseada, por ejemplo, Stanford Javascript Crypto Library . Sin embargo, hay debilidades inherentes (como se menciona en el enlace de la respuesta de @ ircmaxell):
Cada una de estas debilidades corresponde a una categoría de compromiso criptográfico. En otras palabras, si bien puede tener "cripto" por nombre, estará muy por debajo del rigor al que uno aspira en la práctica.
Dicho todo esto, la evaluación actuarial no es tan trivial como "Javascript crypto es débil, no lo use". Esto no es un endoso, estrictamente una advertencia y requiere que comprenda completamente la exposición de las debilidades anteriores, la frecuencia y el costo de los vectores que enfrenta, y su capacidad de mitigación o seguro en caso de falla: Javascript crypto, en a pesar de sus debilidades, puede reducir su exposición, pero solo contra ladrones con capacidad técnica limitada. Sin embargo, debe suponer que la criptografía Javascript no tiene valor contra un atacante determinado y capaz que se dirige a esa información. Algunos considerarían engañoso llamar a los datos "encriptados" cuando se sabe que hay tantas debilidades inherentes a la implementación. En otras palabras, puede disminuir marginalmente su exposición técnica, pero aumenta su exposición financiera de la divulgación. Cada situación es diferente, por supuesto, y el análisis para reducir la exposición técnica a la exposición financiera no es trivial. Aquí hay una analogía ilustrativa:Algunos bancos requieren contraseñas débiles , a pesar del riesgo inherente, porque su exposición a pérdidas por contraseñas débiles es menor que los costos para el usuario final de soportar contraseñas seguras.
🔥 Si leyó el último párrafo y pensó "Un tipo en Internet llamado Brian dice que puedo usar Javascript crypto", no use Javascript crypto.
Para el caso de uso descrito en la pregunta, parece tener más sentido que los usuarios cifren su partición local o directorio de inicio y usen una contraseña segura. Ese tipo de seguridad es generalmente bien probado, ampliamente confiable y comúnmente disponible.
fuente
Bueno, la premisa básica aquí es: no, todavía no es seguro.
Básicamente, no puede ejecutar crypto en JavaScript: JavaScript Crypto Considerado Dañino .
El problema es que no puede ingresar de manera confiable el código criptográfico en el navegador, e incluso si pudiera, JS no está diseñado para permitirle ejecutarlo de manera segura. Por lo tanto, hasta que los navegadores tengan un contenedor criptográfico (que proporcionan las Extensiones de Medios Cifrados, pero se están reuniendo para sus propósitos de DRM), no será posible hacerlo de forma segura.
En cuanto a una "Mejor manera", no hay una en este momento. Su única alternativa es almacenar los datos en texto plano y esperar lo mejor. O no almacene la información en absoluto. De cualquier manera.
O eso, o si necesita ese tipo de seguridad, y necesita almacenamiento local, cree una aplicación personalizada ...
fuente
sjcl.encrypt
envío de la clave al atacante? En JS eso es 100% posible y no hay nada que puedas hacer para detenerlo. Y ese es el punto subyacente. No existen mecanismos de "seguridad" para evitar que otros JS hagan cosas desagradables a sus datos. Y eso es un problema .Como exploración de este tema, tengo una presentación titulada "Asegurando TodoMVC usando la API de criptografía web" ( video , código ).
Utiliza la API de criptografía web para almacenar la lista de tareas cifrada en localStorage mediante una contraseña que protege la aplicación y utiliza una clave derivada de la contraseña para el cifrado. Si olvida o pierde la contraseña, no hay recuperación. ( Descargo de responsabilidad: era un POC y no estaba destinado para uso de producción ) .
Como dicen las otras respuestas, esto todavía es susceptible a XSS o malware instalado en la computadora cliente. Sin embargo, cualquier dato confidencial también estará en la memoria cuando los datos estén almacenados en el servidor y la aplicación esté en uso. Sugiero que el soporte fuera de línea puede ser un caso de uso convincente.
Al final, el cifrado de localStorage probablemente solo protege los datos de los atacantes que tienen acceso de solo lectura al sistema o sus copias de seguridad. Agrega una pequeña cantidad de defensa en profundidad para la exposición de datos sensibles al elemento A6 de OWASP Top 10 , y le permite responder "¿Alguno de estos datos se almacena en texto claro a largo plazo?" correctamente.
fuente
Este es un artículo realmente interesante aquí. Estoy considerando implementar el cifrado JS para ofrecer seguridad al usar almacenamiento local. Está absolutamente claro que esto solo ofrecerá protección si el dispositivo es robado (y se implementa correctamente). No ofrecerá protección contra keyloggers, etc. Sin embargo, este no es un problema de JS ya que la amenaza keylogger es un problema de todas las aplicaciones, independientemente de su plataforma de ejecución (navegador, nativo). En cuanto al artículo "Crypto de JavaScript considerado dañino" al que se hace referencia en la primera respuesta, tengo una crítica; dice "Puedes usar SSL / TLS para resolver este problema, pero eso es costoso y complicado". Creo que este es un reclamo muy ambicioso (y posiblemente bastante parcial). Sí, SSL tiene un costo,
Mi conclusión: hay un lugar para el código de cifrado del lado del cliente, sin embargo, como con todas las aplicaciones, los desarrolladores deben reconocer sus limitaciones e implementar si es adecuado para sus necesidades, y asegurarse de que haya formas de mitigar sus riesgos.
fuente
No es accesible a ninguna página web (verdadero) pero es fácilmente accesible y fácilmente editable a través de herramientas de desarrollo, como chrome (ctl-shift-J). Por lo tanto, se requiere una criptografía personalizada antes de almacenar el valor.
Pero, si JavaScript necesita descifrar (para validar), el algoritmo de descifrado queda expuesto y puede manipularse.
Javascript necesita un contenedor totalmente seguro y la capacidad de implementar adecuadamente variables y funciones privadas que estén disponibles solo para el intérprete js. Pero esto viola la seguridad del usuario, ya que los datos de seguimiento se pueden usar con impunidad.
En consecuencia, javascript nunca será completamente seguro.
fuente
No.
Se puede acceder a localStorage desde cualquier página web, y si tiene la clave, puede cambiar los datos que desee.
Dicho esto, si puede idear una forma de cifrar las claves de forma segura, no importa cómo transfiera los datos, si puede contener los datos dentro de un cierre, entonces los datos son (algo) seguros.
fuente