
Isolation et encapsulation sécurisées des arbres DOM en tirant parti de ShadowDOM
⚠️ EXPÉRIMENTAL [WIP] - UTILISATION À VOS RISQUES ET PÉRILS (en savoir plus)
Tentez votre chance avec LavaDome - visitez la démo, ouvrez la console, et faites tout ce qui est en votre pouvoir pour voler le secret au sein de l'instance LavaDome (signalez votre réussite)
Sous les normes web actuelles, il n'existe aucun moyen établi pour isoler sélectivement des sous-arbres du DOM de manière sécurisée. En d'autres termes, nous ne pouvons pas contrôler l'accès à des sections du DOM en accordant l'accès à certaines parties tout en le bloquant pour d'autres si elles partagent le même environnement d'exécution JavaScript.
Nous vivons dans un monde où nous ne pouvons plus faire confiance au code de nos propres applications, et une exécution de même origine ne garantit pas la sécurité. Pour sécuriser des secrets côté frontend, nous devons être capables de présenter du contenu à l'utilisateur tout en nous assurant qu'il ne puisse pas être compromis par du code JavaScript s'exécutant sous la même origine.

Actuellement, ce contenu sensible est simplement rattaché au DOM une fois exporté, ce qui le rend entièrement accessible à toutes les entités s'exécutant dans la même application. En d'autres termes, les parties du code qui ne devraient pas avoir accès à la clé privée pourraient facilement l'extraire en clair, pourvu que le code malveillant ait accès au DOM.
Mais soyez rassurés. Nous pensons que c'est un problème résoluble 👇
LavaDome prend actuellement en charge JavaScript vanilla et React (avec d'autres en préparation)
import { LavaDome as LavaDomeJavaScript } from '@lavamoat/lavadome-javascript';
const root = document.getElementById('root'); const lavadome = new LavaDomeJavaScript(root); lavadome.text(secret); lavadome.copy(); // copy to clipboard
### [React](https://github.com/lavamoat/lavadome/blob/main/packages/react)```javascript
import { LavaDome as LavaDomeReact, toLavaDomeToken } from '@lavamoat/lavadome-react';
function Secret({ text }) {
const {token, copy} = toLavaDomeCapabilities(text);
return <>
<a onClick={copy}> copy to clipboard </a>
<LavaDomeReact token={token} />
</>;
}
Outre le nœud racine, tous les constructeurs acceptent un second argument facultatif d'options:```javascript // javascript new LavaDomeJavaScript(root, { // boolean unsafeOpenModeShadow: false, });
// react function Secret({ text }) { const {token} = toLavaDomeCapabilities(text); return <LavaDomeReact token={token} // boolean unsafeOpenModeShadow={false} /> }
### Utilisation sûre
En raison des limitations du noyau web, afin d'intégrer LavaDome de manière sécurisée, quelques éléments doivent être pris en compte qui exigent un effort actif de la part du développeur intégrateur :
#### Ordre d'exécution
LavaDome, comme tout autre logiciel de sécurité JavaScript, est toujours vulnérable au code qui s'exécute avant lui.
Cela signifie qu'à l'exception du code auquel nous faisons entièrement confiance, LavaDome doit être le premier morceau de code à charger dans le programme de l'application web.
Bien que cela ne signifie pas que le développeur doive l'utiliser immédiatement (mais plutôt seulement lorsqu'il en a besoin), il doit cependant inclure le programme dès que possible.
Pour ce faire correctement (en toute sécurité), il doit être la première déclaration import/require de tout le programme :```javascript
import '@lavamoat/lavadome-react';
import 'other-stuff';
console.log('Program starts here');
De cette façon, nous garantissons que LavaDome a le temps de se préparer pour une utilisation sûre.
Notez que cela s'applique de la même manière au reste des paquets LavaDome, pas seulement à @lavamoat/lavadome-react (il n'est donc pas nécessaire d'en importer plus d'un).
Rendez-vous dans Security(codage défensif) pour en savoir plus.
En raison des attaques par canal auxiliaire et des limitations du web, l'importation de polices distantes peut être une technique efficace contre LavaDome. Étant donné que cela est intégré dans les domaines du CSS, il n'est actuellement pas possible de résoudre ce problème via LavaDome.
Heureusement, cela peut être traité efficacement avec la directive font-src de la CSP.
Pour atténuer cette forme d'attaque, assurez-vous que votre application web n'autorise pas le chargement de polices depuis des serveurs inconnus.
Rendez-vous dans Security(canal auxiliaire) pour en savoir plus.
Le texte fourni à LavaDome par le développeur doit être imprévisible à 100 %, sinon il peut être attaqué et divulgué.
Ainsi, si votre application doit afficher "your key is 234789", cela signifie que votre structure DOM devrait être :```html
your key is 234789
et ne doit pas être :```html
<span> <lavadome>your key is 234789</lavadome> </span>
Passez à Sécurité (trouvabilité) pour en savoir plus.
Intégrer LavaDome peut être délicat dans le contexte de son test, car puisque LavaDome fait du bon travail pour cacher le secret, il le cache également très bien de vos tests !
Pour intégrer avec succès LavaDome dans votre environnement de test, vous pourriez avoir besoin de l'aide de LavaDomeDebug, qui est exporté par @lavamoat/lavadome-core :```javascript
// IMPORT/USE FOR TESTING/DEBUGGING PURPOSES ONLY - NEVER IN PRODUCTION!
import { LavaDomeDebug } from '@lavamoat/lavadome-core';
Voici quelques-unes des méthodes utilitaires de débogage exportées par `LavaDomeDebug` qui peuvent vous aider à tester les composants basés sur `LavaDome` :
#### `getTextByRoot()`
Étant donné une racine à laquelle `LavaDome` est attaché, `getTextByRoot()` extrait et reconstruit récursivement le secret interne. Pour ce faire, l'instance `LavaDome` doit avoir été initialisée à l'origine avec l'option NON SÛRE `@unsafeOpenModeShadow`, qui rend les ombres internes de `LavaDome` accessibles depuis l'extérieur.