Le stockage local peut-il jamais être considéré comme sécurisé? [fermé]

161

Je suis obligé de développer une application Web qui fonctionnera hors ligne pendant de longues périodes. Pour que cela soit viable, je ne peux pas éviter de sauvegarder des données sensibles (données personnelles mais pas le type de données que vous ne stockeriez que hachées) dans le stockage local.

J'accepte que ce n'est pas une pratique recommandée, mais étant donné peu de choix, je fais ce qui suit pour sécuriser les données:

  • cryptage de tout ce qui entre dans le stockage local à l'aide de la bibliothèque de cryptage javascript stanford et AES-256
  • le mot de passe utilisateur est la clé de cryptage et n'est pas stocké sur l'appareil
  • servir tout le contenu (en ligne) à partir d'un seul serveur de confiance via SSL
  • valider toutes les données allant et venant du stockage local sur le serveur à l'aide du projet owasp antisamy
  • dans la section réseau de l'appcache, sans utiliser *, mais en répertoriant uniquement les URI requis pour la connexion avec le serveur de confiance
  • en général essayer d'appliquer les directives suggérées dans la feuille de triche OWASP XSS

J'apprécie que le diable soit souvent dans les détails, et je sais qu'il y a beaucoup de scepticisme sur le stockage local et la sécurité basée sur javascript en général. Quelqu'un peut-il dire s'il y a:

  • défauts fondamentaux de l'approche ci-dessus?
  • des solutions possibles pour de tels défauts?
  • un meilleur moyen de sécuriser le stockage local lorsqu'une application html 5 doit fonctionner hors ligne pendant de longues périodes?

Merci pour toute aide.

user1173706
la source
"J'accepte que ce n'est pas une pratique recommandée" - Est-ce le cas? N'est-ce pas le contraire qu'il a été créé pour cela?
hakre
2
Pour clarifier, je voulais dire une pratique non recommandée pour stocker des données sensibles dans un stockage local.
user1173706
Comme ça, vous ne devriez pas transmettre de données sensibles sur de grands réseaux?
hakre
@ user1173706 Pourquoi l'application doit-elle fonctionner pendant de longues périodes hors ligne? À quoi ressemblent les utilisateurs? Quels navigateurs devez-vous prendre en charge? Pour ma part, je pense que c'est possible, mais j'ai besoin de connaître les détails de votre scénario.
Benjamin Gruenbaum
@Benjamin j'ai mis à jour la question. Merci.
user1173706

Réponses:

74

WebCrypto

Les problèmes de cryptographie dans javascript côté client (navigateur) sont détaillés ci-dessous. Toutes ces préoccupations sauf une ne s'appliquent pas à l' API WebCrypto , qui est maintenant raisonnablement bien prise en charge .

Pour une application hors ligne, vous devez toujours concevoir et implémenter un magasin de clés sécurisé.

A part: si vous utilisez Node.js, utilisez l' API crypto intégrée .

Cryptographie native-Javascript (pré-WebCrypto)

Je suppose que la principale préoccupation est une personne ayant un accès physique à l'ordinateur lisant le localStoragepour votre site, et vous voulez que la cryptographie aide à empêcher cet accès.

Si quelqu'un a un accès physique, vous êtes également exposé à des attaques autres et pires que la lecture. Ceux-ci incluent (mais ne sont pas limités à): les enregistreurs de frappe, la modification de script hors ligne, l'injection de script local, l'empoisonnement du cache du navigateur et les redirections DNS. Ces attaques ne fonctionnent que si l'utilisateur utilise la machine après qu'elle a été compromise. Néanmoins, l'accès physique dans un tel scénario signifie que vous avez de plus gros problèmes.

Gardez donc à l'esprit que le scénario limité où la cryptographie locale est précieuse serait si la machine est volée.

Il existe des bibliothèques qui implémentent les fonctionnalités souhaitées, par exemple Stanford Javascript Crypto Library . Il y a cependant des faiblesses inhérentes (comme indiqué dans le lien de la réponse de @ ircmaxell):

  1. Manque d'entropie / génération de nombres aléatoires;
  2. Absence de fichier de clés sécurisé, c'est-à-dire que la clé privée doit être protégée par mot de passe si elle est stockée localement, ou stockée sur le serveur (ce qui interdit l'accès hors ligne);
  3. Manque d'effacement sécurisé;
  4. Manque de caractéristiques de synchronisation.

Chacune de ces faiblesses correspond à une catégorie de compromis cryptographique. En d'autres termes, alors que vous pouvez avoir "crypto" par nom, ce sera bien en dessous de la rigueur à laquelle on aspire dans la pratique.

Cela étant dit, l'évaluation actuarielle n'est pas aussi triviale que «la crypto Javascript est faible, ne l'utilisez pas». Ce n'est pas une approbation, strictement une mise en garde et cela vous oblige à comprendre complètement l'exposition des faiblesses ci-dessus, la fréquence et le coût des vecteurs auxquels vous faites face, et votre capacité d'atténuation ou d'assurance en cas de panne: crypto Javascript, en malgré ses faiblesses, peut réduire votre exposition mais uniquement contre les voleurs aux capacités techniques limitées. Cependant, vous devez présumer que la crypto Javascript n'a aucune valeur contre un attaquant déterminé et capable qui cible ces informations. Certains jugeraient trompeur d'appeler les données «cryptées» alors que tant de faiblesses sont connues pour être inhérentes à la mise en œuvre. En d'autres termes, vous pouvez réduire légèrement votre exposition technique, mais vous augmentez votre exposition financière grâce à la divulgation. Chaque situation est différente, bien sûr - et l'analyse de la réduction de l'exposition technique à l'exposition financière n'est pas anodine. Voici une analogie illustrative:Certaines banques exigent des mots de passe faibles , malgré le risque inhérent, car leur exposition aux pertes dues à des mots de passe faibles est inférieure aux coûts de prise en charge des mots de passe forts pour l'utilisateur final.

🔥 Si vous lisez le dernier paragraphe et que vous vous dites: "Un type sur Internet nommé Brian dit que je peux utiliser le crypto Javascript", n'utilisez pas le crypto Javascript.

Pour le cas d'utilisation décrit dans la question, il semblerait plus judicieux pour les utilisateurs de crypter leur partition locale ou leur répertoire personnel et d'utiliser un mot de passe fort. Ce type de sécurité est généralement bien testé, largement approuvé et couramment disponible.

Brian M. Hunt
la source
Il existe une documentation supplémentaire (citations) disponible pour la position générale de "ne pas utiliser de crypto JavaScript" fournie par le groupe NCC à partir de 2011: Cryptographie JavaScript considérée comme nuisible (notamment en raison de la capture-22 du téléchargement de l'outil pour vérifier les téléchargements ... qualité PRNG … Etc.)
amcgregor
58

Eh bien, le principe de base ici est: non, ce n'est pas encore sécurisé.

Fondamentalement, vous ne pouvez pas exécuter de crypto en JavaScript: la crypto JavaScript est considérée comme nuisible .

Le problème est que vous ne pouvez pas obtenir de manière fiable le code cryptographique dans le navigateur, et même si vous le pouviez, JS n'est pas conçu pour vous permettre de l'exécuter en toute sécurité. Ainsi, tant que les navigateurs n'auront pas un conteneur cryptographique (fourni par Encrypted Media Extensions, mais contre lequel ils se rallient à leurs fins DRM), il ne sera pas possible de le faire en toute sécurité.

En ce qui concerne le "meilleur moyen", il n'y en a pas pour le moment. Votre seule alternative est de stocker les données en texte brut et d'espérer le meilleur. Ou ne stockez pas du tout les informations. D'une manière ou d'une autre.

Soit cela, soit si vous avez besoin de ce type de sécurité et que vous avez besoin d'un stockage local, créez une application personnalisée ...

ircmaxell
la source
8
Downvoter: pouvez-vous fournir une meilleure réponse? Je me rends compte que c'est une question quelque peu controversée où il y a un désaccord important entre les professionnels de la sécurité (et les non-professionnels également), donc le point de vue alternatif mériterait d'être partagé. À moins que vous ne votiez pour une autre raison, dans quel cas comment puis-je améliorer cette réponse?
ircmaxell
9
@ircmaxell pas moi, mais je ne suis pas d'accord avec cette réponse. "Le problème est que vous ne pouvez pas obtenir de manière fiable le code cryptographique dans le navigateur, et même si vous le pouviez, JS n'est pas conçu pour vous permettre de l'exécuter en toute sécurité." - Pourquoi? Quel est le problème inhérent ? Vous pouvez utiliser la bibliothèque de cryptage JavaScript de Stanford et y crypter / décrypter. Vous pouvez hacher et tout faire en toute sécurité. Je ne vois pas le problème inhérent ici dans une application hors ligne dans JS faisant crpyto standard, un peu comme le ferait une application construite dans une autre langue.
Benjamin Gruenbaum
11
@BenjaminGruenbaum: le problème est qu'il y a plusieurs endroits où ce crypto-code aurait besoin d'interagir avec du code tiers. L'intérêt de cet article auquel j'ai lié est que vous ne pouvez pas contrôler l'environnement d'exécution. Vous installez donc la bibliothèque Stanford Crypto. Alors que se passe-t-il si un plugin de navigateur remplace sjcl.encryptpour envoyer la clé par courrier électronique à l'attaquant? Dans JS, c'est possible à 100% et vous ne pouvez rien faire pour l'arrêter. Et c'est le point sous-jacent. Il n'y a pas de mécanismes de «sécurité» en place pour empêcher d'autres JS de faire des choses désagréables à vos données. Et c'est un problème .
ircmaxell
13
@ircmaxell Si vous dormez avec des chiens, vous ne pouvez pas vous attendre à ne pas vous réveiller avec des puces. Si l'utilisateur installe un logiciel malveillant complémentaire qui est exactement le même que l'utilisateur installant un virus sur son PC, il n'en est pas différent. Votre programme Java ou C peut être aussi sécurisé que possible, mais dès que l'attaquant a la capacité d'exécuter du code, vous êtes foutu. Ce n'est pas différent pour JS. Les modules complémentaires n'apparaissent pas simplement comme par magie dans le navigateur. De plus, ne pas enregistrer les informations cryptées n'aiderait en aucun cas si l'utilisateur a un logiciel malveillant, car il pourrait simplement détourner les données en direct.
Benjamin Gruenbaum
9
@BenjaminGruenbaum: pas d'accord. Dans une application normale, vous devez soit compromettre l'application elle-même (pour lire les emplacements de mémoire), soit obtenir un accès root à la boîte (compromettre le système d'exploitation). Quoi qu'il en soit, vous devez compromettre quelque chose de plus profond que simplement faire un comportement normal. JS permet cela dans un comportement normal. Quel est le problème ...
ircmaxell
12

Pour explorer ce sujet, j'ai une présentation intitulée «Sécuriser TodoMVC à l'aide de l'API de cryptographie Web» ( vidéo , code ).

Il utilise l' API Web Cryptography pour stocker la liste de tâches chiffrée dans localStorage en protégeant l'application par mot de passe et en utilisant une clé dérivée de mot de passe pour le chiffrement. Si vous oubliez ou perdez le mot de passe, il n'y a pas de récupération. ( Clause de non-responsabilité - il s'agissait d'un POC et non destiné à une utilisation en production. )

Comme l'indiquent les autres réponses, cela est toujours sensible au XSS ou aux logiciels malveillants installés sur l'ordinateur client. Cependant, toutes les données sensibles seraient également en mémoire lorsque les données sont stockées sur le serveur et que l'application est en cours d'utilisation. Je suggère que le support hors ligne peut être le cas d'utilisation convaincant.

En fin de compte, le chiffrement de localStorage ne protège probablement les données que des attaquants qui ont un accès en lecture seule au système ou à ses sauvegardes. Il ajoute une petite quantité de défense en profondeur pour OWASP Top 10 item A6-Sensitive Data Exposure , et vous permet de répondre "Est-ce que certaines de ces données sont stockées en texte clair à long terme?" correctement.

Kevin Hakanson
la source
3

C'est un article vraiment intéressant ici. J'envisage d'implémenter le cryptage JS pour offrir la sécurité lors de l'utilisation du stockage local. Il est absolument clair que cela n'offrira une protection que si l'appareil est volé (et mis en œuvre correctement). Il n'offrira pas de protection contre les enregistreurs de frappe, etc. Cependant, ce n'est pas un problème JS car la menace de l'enregistreur de frappe est un problème de toutes les applications, quelle que soit leur plate-forme d'exécution (navigateur, natif). En ce qui concerne l'article "JavaScript Crypto Considéré Nocif" référencé dans la première réponse, j'ai une critique; il indique "Vous pouvez utiliser SSL / TLS pour résoudre ce problème, mais c'est cher et compliqué". Je pense que c'est une affirmation très ambitieuse (et peut-être plutôt biaisée). Oui, SSL a un coût,

Ma conclusion - Il y a une place pour le code de chiffrement côté client, mais comme pour toutes les applications, les développeurs doivent reconnaître ses limites et les implémenter si cela convient à leurs besoins, et s'assurer qu'il existe des moyens d'atténuer ses risques.

Paul S
la source
Historiquement, il y a eu des coûts extraordinaires (mécaniques et non financiers) associés à la négociation initiale de la connexion. Au point que les entreprises utiliseraient des appliances de terminaison SSL dédiées, ce qui pourrait devenir financièrement coûteux au-delà des frais d'émission de certificats et d'assurance. Aujourd'hui, beaucoup de ces problèmes ont été résolus, tels que la persistance de session de durée prolongée pour éviter la négociation initiale sur les demandes suivantes.
amcgregor le
2

N'est accessible à aucune page Web (true) mais est facilement accessible et facilement modifiable via des outils de développement, tels que chrome (ctl-shift-J). Par conséquent, une cryptographie personnalisée est requise avant de stocker la valeur.

Mais, si javascript a besoin de déchiffrer (pour valider), alors l'algorithme de déchiffrement est exposé et peut être manipulé.

Javascript a besoin d'un conteneur entièrement sécurisé et de la capacité d'implémenter correctement des variables privées et des fonctions qui ne sont disponibles que pour l'interpréteur js. Mais cela viole la sécurité des utilisateurs, car les données de suivi peuvent être utilisées en toute impunité.

Par conséquent, javascript ne sera jamais totalement sécurisé.

Rockmo
la source
-29

Non.

localStorage est accessible par n'importe quelle page Web, et si vous avez la clé, vous pouvez modifier les données que vous voulez.

Cela étant dit, si vous pouvez concevoir un moyen de crypter les clés en toute sécurité, peu importe la façon dont vous transférez les données, si vous pouvez contenir les données dans une fermeture, les données sont (un peu) sûres.

hellol11
la source
19
Il n'est accessible à "aucune page Web". Il n'est accessible qu'aux pages du domaine actuel.
dtabuenc
@dtabuenc au contraire, j'ai créé il y a quelque temps un stylo qui vous montre chaque paire clé / valeur dans votre stockage local , sans aucun piratage.
hellol11
3
Nan! Désolé. Le stockage local est isolé par domaine. Le code exécuté dans un domaine ne peut pas accéder aux valeurs stockées dans le stockage local par un autre domaine. Par exemple, google.com stocke un tas de choses dans le stockage local. Vous ne pourrez répertorier aucune des clés de google.com dans votre exemple de stylet.
dtabuenc
@dtabuenc l'a testé, vous avez raison.
hellol11