web-dev-qa-db-fra.com

Le stockage local peut-il être considéré comme sécurisé?

Je suis tenu 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 la mémoire de stockage locale.

J'accepte le fait que ce ne soit pas une pratique recommandée, mais étant donné le peu de choix possible, je procède comme suit pour sécuriser les données:

  • chiffrer tout ce qui entre dans le stockage local en utilisant la bibliothèque de cryptographie javascript stanford et AES-256
  • le mot de passe de l'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 sur ssl
  • validation de toutes les données en provenance et à destination du stockage local sur le serveur à l'aide du projet owasp antisamy
  • dans la section réseau de appcache, sans utiliser *, mais en listant uniquement les URI requis pour la connexion au serveur de confiance
  • en général, essayer d'appliquer les directives suggérées dans le aide-mémoire OWASP XSS

J'apprécie que le diable soit souvent dans les détails et je sais qu'il existe beaucoup de scepticisme quant au 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 dans 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.

145
user1173706

WebCrypto

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

Pour une application hors ligne, vous devez toujours concevoir et mettre en œuvre un fichier de clés sécurisé.

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

Cryptographie Javascript native (pré-WebCrypto)

Je présume que la principale préoccupation concerne une personne ayant un accès physique à l’ordinateur qui lit la localStorage de votre site et vous souhaitez une cryptographie pour empêcher cet accès.

Si quelqu'un a un accès physique, vous êtes également ouvert à des attaques autres et pires que la lecture. Ceux-ci incluent (sans s'y limiter): 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 que celle-ci ait été compromise. Néanmoins, l'accès physique dans un tel scénario signifie que vous avez de plus gros problèmes.

Alors gardez à l'esprit que le scénario limité dans lequel la crypto locale est précieuse serait le cas si la machine est volée.

Certaines bibliothèques implémentent la fonctionnalité souhaitée, par exemple Bibliothèque de cryptographie Javascript de Stanford . Il existe cependant des faiblesses inhérentes (comme indiqué dans le lien de la réponse de @ ircmaxell):

  1. Absence de génération d'entropie/nombre aléatoire;
  2. Absence de magasin de clés sécurisé, c’est-à-dire que la clé privée doit être protégée par un mot de passe si elle est stockée localement ou sur le serveur (ce qui interdit l’accès hors connexion);
  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, bien que votre nom soit "crypto", il sera bien en deçà de la rigueur à laquelle on aspire en pratique.

Cela étant dit, l’évaluation actuarielle n’est pas aussi triviale que "le crypto javascript est faible, ne l’utilisez pas". Ceci n’est pas une approbation, mais une stricte mise en garde et vous oblige à comprendre parfaitement la mise en évidence des faiblesses ci-dessus, la fréquence et le coût des vecteurs que vous rencontrez, ainsi que votre capacité à atténuer ou à assurer l’assurance en cas d’échec: crypto Javascript, en malgré ses faiblesses, peut réduire votre exposition mais uniquement contre les voleurs avec une capacité technique limitée. Cependant, vous devriez supposer que la cryptographie Javascript n'a aucune valeur contre un attaquant déterminé et capable qui cible cette information. Certains jugeraient trompeur d'appeler les données "cryptées" alors que de nombreuses 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 par la divulgation. Bien entendu, chaque situation est différente - et l’analyse de la réduction de l’exposition technique à une 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 aux mots de passe faibles est inférieure aux coûts supportés par l'utilisateur final pour prendre en charge des mots de passe forts.

???? Si vous lisez le dernier paragraphe et pensez "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 logique que les utilisateurs chiffrent leur partition locale ou leur répertoire de base et utilisent un mot de passe fort. Ce type de sécurité est généralement bien testé, largement fiable et communément disponible.

66
Brian M. Hunt

Le principe de base est le suivant: non, ce n’est pas encore sécurisé.

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

Le problème est que vous ne pouvez pas obtenir le code crypté de manière fiable 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 qu’ils seront utilisés pour leurs besoins de gestion des droits numériques), il ne sera pas possible de le faire en toute sécurité.

En ce qui concerne une "meilleure façon", 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 l'information du tout. D'une manière ou d'une autre.

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

56
ircmaxell

Pour explorer ce sujet, j'ai présenté un exposé intitulé "Sécurisation de TodoMVC à l'aide de l'API de cryptographie Web" ( vidéo , code ).

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

Comme l’indique l’autre réponse, il est toujours vulnérable à XSS ou à un logiciel malveillant installé 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 que les données des attaquants disposant d'un accès en lecture seule au système ou à ses sauvegardes. Il ajoute une petite défense en profondeur pour l'élément OWASP Top 10 A6-Sensitive Data Exposure , et vous permet de répondre: "Certaines de ces données sont-elles stockées en texte clair à long terme?" correctement.

12
Kevin Hakanson

C'est un article vraiment intéressant ici. J'envisage de mettre en œuvre le cryptage JS pour offrir une sécurité lors de l'utilisation du stockage local. Il est tout à fait clair que cela n'offrira une protection que si l'appareil est volé (et correctement implémenté). Il n'offrira pas de protection contre les enregistreurs de frappe, etc. Cependant, il ne s'agit pas d'un problème de JS car la menace des enregistreurs de frappe concerne toutes les applications, quelle que soit leur plate-forme d'exécution (navigateur, natif). En ce qui concerne l'article "Crypto JavaScript considéré comme nuisible" référencé dans la première réponse, j'ai une critique; "Vous pouvez utiliser SSL/TLS pour résoudre ce problème, mais cela coûte cher et est compliqué". Je pense que cette affirmation est très ambitieuse (et peut-être plutôt biaisée). Oui, SSL a un coût, mais si vous examinez le coût de développement d'applications natives pour plusieurs systèmes d'exploitation plutôt que sur le Web en raison de ce problème uniquement, le coût de SSL devient insignifiant.

Ma conclusion - Il existe une place pour le code de chiffrement côté client. Cependant, comme pour toutes les applications, les développeurs doivent reconnaître ses limites et les mettre en œuvre si cela convient à leurs besoins, tout en veillant à ce qu'il soit possible d'atténuer ses risques.

3
Paul S

N'est accessible à aucune page Web (true) mais est facilement accessible et éditable via des outils de développement, tels que chrome (ctl-shift-J). Par conséquent, une crypto 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 nécessite un conteneur entièrement sécurisé et la capacité d'implémenter correctement les variables privées et les fonctions disponibles uniquement pour l'interpréteur js. Mais cela viole la sécurité de l'utilisateur, car les données de suivi peuvent être utilisées en toute impunité.

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

1
rockmo