Design: Expliquer la sécurité

Créé le 19 juin 2015  ·  26Commentaires  ·  Source: WebAssembly/design

Le modèle de sécurité de WebAssembly vise à protéger les utilisateurs contre les fichiers .wasm bogués ou malveillants. Cela n'aide pas les développeurs à écrire des applications sécurisées ! Notre conception doit clarifier cette distinction, expliquer comment WebAssembly implémente cette sécurité et quels outils WebAssembly s'attend à ce qu'ils soient disponibles pour aider les développeurs à créer des applications sécurisées (cela repose sur l'offre des bonnes primitives dans WebAssembly).

C'est surtout un problème pour moi d'ajouter cela dans la conception.

Tous les 26 commentaires

Salut!

J'ai une question : serait-il judicieux de développer les éléments suivants dans ce contexte :

"En dehors de cela, les programmes qui invoquent un comportement indéfini au niveau du langage source peuvent être compilés dans des programmes WebAssembly qui font autre chose, y compris corrompre le contenu du tas d'applications, appeler des API avec des paramètres arbitraires, suspendre, piéger ou consommer des quantités arbitraires de ressources (dans les limites)."
https://github.com/WebAssembly/design/blob/master/CAndC++.md#undefined-and-implementation-defined-behavior

Ce à quoi je pense, c'est de fournir un contexte / des références qui peuvent être (peut-être) utiles pour les développeurs Web venant de milieux non natifs - en fournissant des exemples et des discussions plus approfondies.

Par exemple, le MSC14-C du CERT Ne pas introduire de dépendances de plate-forme inutiles répertorie quatre types différents de comportement non portable (comportement non spécifié, comportement non défini, comportement spécifique aux paramètres régionaux, comportement défini par l'implémentation) avec des exemples. MSC15-CPP. Les compilateurs C peuvent ignorer silencieusement certaines vérifications en boucle , ce qui peut être particulièrement remarquable dans ce contexte (Robert Seacord en parle plus en détail dans "Silent Elimination of Bounds Checks" ).

Des soins plus approfondis :

Autres conseils potentiellement pertinents :

Le fait d'avoir un en-tête CSP unique pour contrôler les fichiers wasm serait-il utile ? J'ai l'impression que les propriétaires de sites pourraient vouloir empêcher les sous-ressources de charger wasm.

C'est une question intéressante. Nous devrions certainement autoriser les sites à interdire le chargement dynamique et l'évaluation de WebAssembly dans les mêmes cas qu'ils interdisent eval et Function (cela ne ferait que tomber de l'intégration du module ES6 et des contrôles CSP sur le Loader chemin). Au-delà de cela, cependant, puisque WebAssembly sera équivalent à JS, je ne pense pas qu'il serait nécessaire de distinguer les deux.

Il vaut la peine de pointer le numéro 53 pour une discussion sur certains des problèmes de sécurité liés à la liaison dynamique.

@jfbastien yup

@lukewagner Je suppose que cela dépend de l'accès de bas niveau aux ressources que wasm permettra. Comme vous le dites hors de la boîte, c'est juste JS. Cependant, il semble que l'objectif primordial du wasm soit la chose la plus proche possible du métal des machines; une directive CSP pour contrôler globalement serait une bonne chose à avoir.
Au fil du temps, une approche plus granulaire des autres fonctionnalités serait également préférable.

Les autres possibilités immédiates sont l'utilisation de l'API des autorisations pour d'autres accès de bas niveau.

Eh bien, proche du métal dans le sens de la performance. Du point de vue de la sécurité, des autorisations et du sandboxing, il n'est pas question que WebAssembly diverge de JS.

Ce n'est pas le sentiment que j'ai eu des annonces post-MVP et Brendan Eichs mais ok :+1:

Je pense que ce à quoi vous faites référence, c'est que nous avons convenu que, post-MVP, la sémantique WebAssembly serait autorisée à diverger de ce qui pourrait être efficacement polyrempli dans JS. Cette divergence concernerait les fonctionnalités de calcul, rien à voir avec la sécurité/les autorisations. Cela signifie que, bien qu'elles ne puissent pas être remplies _efficacement_, les nouvelles fonctionnalités _pourraient_ être simulées par un interpréteur WebAssembly écrit en JS ( Emterpreter-style ). Il serait probablement bon d'ajouter une note à cet effet pour délimiter ce que nous entendons par "diverger de JS".

Oui, ce serait certainement une bonne amélioration du document, j'ai peut-être lu le document trop vite mais cela ne semble pas être clair.

Je pense que c'était l'une des discussions d'Eich sur l'ajout de fonctionnalités de threading et de mémoire qui m'a fait penser que wasm obtiendrait de nouvelles fonctionnalités. Je soupçonne que ceux-ci seront également ajoutés à JavaScript et soumis à l'examen habituel des nouvelles fonctionnalités.

"Pas différent du POV de sécurité que JS" est maintenant dans Web.md .

Je préférerais mieux expliquer la distinction. Faire référence à JS n'est pas très agréable d'un point de vue autonome, et je pense que nous voulons en fait réduire la surface de sécurité dont dispose JS (disons, les scripts d'origine croisée et autres).

Je vais y arriver, maintenant que j'en ai parlé à la CppCon :-)

Pour ceux qui pourraient être intéressés par l'utilisation de WebAssembly comme cible pour les implémentations cryptographiques, il serait utile de détailler les différences entre le JIT JS/asm.js et le JIT WebAssembly en termes de prise en charge des implémentations à temps fixe. Je pense spécifiquement aux opérations telles que les décalages de bits, les branches introduites après le JIT, les sauts ou les recherches conditionnels, ou d'autres modifications que le JIT peut apporter et qui pourraient introduire des fuites de synchronisation.

Si les développeurs ne doivent pas s'attendre à ce que WebAssembly prenne mieux en charge les implémentations à durée fixe que ce que nous avons déjà avec asm.js, il serait alors utile de préciser que cela serait utile dans le cadre de l'élaboration des implications de sécurité de WebAssembly pour la conception d'applications. Si WebAssembly fournit des moyens de mieux renforcer les applications par rapport à ce qui existe actuellement (maintenant ou après MVP, je n'ai pas lu la spécification en profondeur), ce serait également formidable de développer. https://github.com/jedisct1/libsodium.js/issues/24#issuecomment -128002942 a un peu plus sur les problèmes existants autour de la crypto JavaScript côté client.

Tout cela est très excitant, d'ailleurs. :RÉ

Nous avons convenu que nous devrions avoir une déclaration de clarification comme suggéré par @dconnolly. Pour l'instant, les discussions que nous avons eues étaient que pour MVP, il n'y aurait aucune garantie sur ce que le JIT peut / ne peut pas faire, et que les algorithmes à temps constant ne sont pas la bonne utilisation de wasm, du moins pour MVP. Cela peut changer à l'avenir.

Mon point de vue actuel est que les API externes (telles que proposées par l'embedder comme la plate-forme Web) sont mieux placées pour offrir de telles garanties, car vous avez souvent besoin d'un assemblage et d'une bonne compréhension de la micro-architecture pour écrire un code à temps constant approprié. Considérez l'exemple extrême d'un processeur effectuant une traduction binaire dynamique : WebAssembly ne peut pas garantir ce qu'un processeur peut/ne peut pas faire. Mon point de vue est que WebAssembly est à un niveau d'abstraction trop élevé pour exprimer un véritable code à temps constant.

Cool, merci pour la précision. Convenu que les API de plate-forme Web sont le meilleur endroit pour ce genre de chose, en particulier les primitives ( WebCrypto prend / prendra en charge l'essentiel, avec de la place pour de futurs ajouts comme de nouvelles courbes elliptiques via des notes ). Dans l'attente de ce langage supplémentaire sur la sécurité, il aidera tous ceux qui pourraient mal interpréter les implications de WebAssembly. :+1:

@jfbastien , est-ce que tout ce que vous avez dit sur les garanties de timing wasm s'applique toujours aujourd'hui ?

Je vois dans les documents actuels que l'exécution déterministe est un objectif, sauf dans une petite liste de cas limites documentés, ce qui semble potentiellement positif pour les algorithmes à temps constant. Cependant, webassembly.org/docs/security reconnaît que les attaques de synchronisation sont possibles et répertorie certaines mesures d'atténuation futures potentielles, mais il n'est pas clair si l'implication est censée être que "votre code C bogué ne sera pas corrigé par magie... encore" ou "des vulnérabilités de canaux secondaires peuvent être introduites qui ne se produiraient pas avec un compilateur C typique".

Mis à part les garanties dures, il serait utile au moins d'avoir une idée de notre position entre "les algorithmes à temps constant seront définitivement foutus à 100%" et "il n'y a aucune raison évidente de ne pas toujours s'attendre à des caractéristiques de synchronisation comparables à la sortie binaire native de clang". Au point de @dconnolly , un langage comparant spécifiquement cela avec asm.js serait également très utile - en particulier en tenant compte des deux implémentations comme Firefox qui respectent pleinement les déclarations 'use asm' et celles comme Chrome qui le jouent un peu plus lâche .

@buu700 résultat déterministe pour tous les opcodes n'implique pas que le timing est garanti pour n'importe quel opcode. Clang ne garantit pas non plus l'exécution à temps constant, et le temps constant n'est pas tout ce dont vous avez besoin si vous écrivez du code sensible aux fuites d'informations.

À l'heure actuelle, WebAssembly ne fait aucune tentative pour garantir quoi que ce soit en ce qui concerne les fuites d'informations.

Compris, merci d'avoir clarifié la section sur le déterminisme @jfbastien.

En ce qui concerne la synchronisation / les canaux secondaires (et en ignorant les garanties ou leur absence), il semble qu'il n'y ait rien de pertinent dans la spécification à ce sujet pour le moment et aucune donnée utile sur la façon dont les implémentations réelles se comparent à clang? Ce à quoi je voulais en venir, après avoir lu votre commentaire précédent, c'est s'il y a une raison inhérente pour que les implémentations de wasm soient nécessairement toujours _pire_ que gcc/clang dans ce domaine. Vous aviez mentionné le niveau d'abstraction comme une préoccupation, mais il n'était pas clair ce que vous utilisiez comme comparaison de base pour une synchronisation constante "assez bonne" (C natif, assemblage, matériel, etc.).

En d'autres termes, étant donné le choix entre l'exécution d'un code sensible aux fuites d'informations sur clang et une implémentation hypothétique meilleure / la plus mature / la plus renforcée contre les fuites d'informations de la spécification WebAssembly d'aujourd'hui, la première serait-elle toujours évidemment préférée en fonction de votre compréhension ?

À ce stade, je ne compterais ni sur clang ni sur WebAssembly pour le code sensible aux infofuites. La seule façon que je connaisse actuellement pour obtenir les garanties que je souhaite est d'écrire un assembly qui lit le manuel du processeur spécifique que je cible, et avec une étroite collaboration avec le noyau. Connaître "x86" ou "ARM 64" n'est même pas suffisant si vous voulez vraiment être indépendant du timing.

Vous pouvez obtenir des garanties avec certains compilateurs / langages, mais si une seule fuite d'informations est tout ce qui est nécessaire pour vaincre votre code, alors "certaines" ne sont pas une garantie suffisante.

Parfait, merci, je pense que cela répond à ma question. D'accord sur tous les points concernant la modélisation générale de la menace des fuites d'informations ; Je voulais juste savoir si wasm devait être considéré comme plus fuyant que n'importe quelle autre cible de compilation C (sans asm), ce qui, semble-t-il, n'est pas nécessairement le cas?

Je ne pense pas que "plus de fuites" soit une mesure utile. La métrique est « ça fuit ? » La réponse pour WebAssembly, clang, C++ et C est "oui".

Eh bien, plus précisément, ce que j'avais en tête, c'était des algorithmes conçus pour atteindre certaines propriétés de résistance des canaux latéraux avec des implémentations en C pur, comme l'exemple de libsodium/NaCl lié par @dconnolly. C'est certainement idéal si quelque chose survit à tous les scénarios d'attaque possibles, mais il est également utile de connaître le delta entre deux choses (même si elles sont toutes les deux nulles, dans une certaine mesure), et dans ce cas si vous utilisez WebAssembly au lieu d'une ABI Linux comme une cible est susceptible de briser le modèle de menace prévu du libsodium.

Le commentaire lié sur le fil de discussion de libsodium est très informatif sur la façon dont la bibliothèque interagit avec asm.js, mais en tant que non-expert, il n'est pas évident pour moi à quoi ressemblerait cette analyse spécifique réécrite pour WebAssembly (à part le support i64 et les navigateurs étant plus cohérent dans la gestion de wasm que asm.js).

Mais de toute façon, je comprends quel était votre point de départ il y a un an maintenant, et tout ce qui me préoccupait vraiment était de savoir si vous faisiez une déclaration plus forte que vous ne l'étiez réellement (c'était parce qu'une spécification était connue pour introduire de nouvelles faiblesses spécifiques dans les canaux secondaires introuvable dans le C/clang standard, contrairement à cela, ni l'un ni l'autre n'est généralement adapté à cette fin), donc merci d'avoir clarifié cela.

>

Je ne pense pas que "plus de fuites" soit une mesure utile.

@jfbastien , la sécurité quantitative est un domaine soucieux de mesurer juste
cette. La métrique commune est le nombre de bits d'information révélés par un
attaque réussie - 1 bit contre 32 bits, disons, fait une énorme différence (et dans
pratique presque chaque système a de petites fuites potentielles à travers le côté
chaînes). Cependant, une telle quantification est souvent assez difficile.

>

Je ne pense pas que "plus de fuites" soit une mesure utile.

@jfbastien , la sécurité quantitative est un domaine soucieux de mesurer juste
cette. La métrique commune est le nombre de bits d'information révélés par un
attaque réussie - 1 bit contre 32 bits, disons, fait une énorme différence (et dans
pratique presque chaque système a de petites fuites potentielles à travers le côté
chaînes). Cependant, une telle quantification est souvent assez difficile.

J'en suis conscient et je ne m'y intéresse pas du tout car une fuite est une fuite. Si cela compte pour les développeurs, cela finira par nous mordre (les implémenteurs de WebAssembly). Je ne pense pas que WebAssembly devrait essayer de résoudre ce problème de si tôt compte tenu de nos autres priorités, et que WebCrypto existe déjà en tant qu'effort (malgré le défaut qu'il pourrait avoir autrement, il est préférable de s'attaquer à ce problème que WebAssembly pour le moment ). Vous pouvez bien sûr explorer cela à votre guise.

@jfbastien , a convenu que ce sujet n'a pas la priorité pour le moment, que
Wasm n'est pas plus leaky que C, et que nous ne connaissons pas de bonnes façons de s'attaquer
ce. Mais des simplifications excessives comme "une fuite est une fuite" ne sont pas utiles dans ce sens
importe -- chaque système fuit dans une certaine mesure, donc la quantité est en fait tout
c'est important. Et attendre que "ça nous morde" n'est pas une stratégie
va inspirer beaucoup de confiance parmi les vraies victimes potentielles, à savoir
utilisateurs du navigateur.

d'accord que ... Wasm n'est pas plus leaky que C

Génial, merci de l'avoir explicitement confirmé ! C'est tout ce pour quoi je suis venu ici : une idée générale de ce à quoi je devrais le comparer, pas une garantie de savoir s'il "ne fuira pas".

@rossberg-chromium Je ne pense pas que je serais d'accord avec l'idée que wasm n'est pas plus fuyant que C. En fin de compte, cela dépend de la façon dont chaque moteur implémente tout. Par exemple, JavaScriptCore hiérarchise le code et arrête de hiérarchiser le code lorsqu'il manque de mémoire exécutable. C'est une fuite qui n'existe pas avec le code C. Je m'attendrais à ce que, à mesure que les moteurs wasm deviennent plus avancés, wasm sera probablement aussi fuyant que quelque chose comme la JVM. En fin de compte, je ne pense pas que les spécifications ou les implémenteurs soient susceptibles de s'efforcer de prévenir les fuites d'informations, surtout pas au détriment des performances.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

frehberg picture frehberg  ·  6Commentaires

ghost picture ghost  ·  7Commentaires

Artur-A picture Artur-A  ·  3Commentaires

mfateev picture mfateev  ·  5Commentaires

dpw picture dpw  ·  3Commentaires