
Isolamento e incapsulamento sicuri degli alberi DOM tramite ShadowDOM
⚠️ SPERIMENTALE [WIP] - USALO A TUO RISCHIO (scopri di più)
Prova a violare LavaDome - visita l'app demo, apri la console, e fai tutto ciò che è in tuo potere per rubare il segreto dall'interno dell'istanza LavaDome (segnala il tuo successo)
Negli standard web odierni, non esiste un modo consolidato per isolare selettivamente i sottoalberi DOM in maniera sicura. In altre parole, non possiamo controllare l'accesso a sezioni del DOM concedendo l'accesso ad alcune parti e bloccandolo per altre se condividono lo stesso ambiente di esecuzione JavaScript.
Viviamo in un mondo in cui non possiamo più fidarci del codice nelle nostre app, e l'esecuzione same-origin non garantisce la sicurezza. Per proteggere i segreti nel frontend, dobbiamo essere in grado di presentare contenuti all'utente assicurando che non possano essere compromessi da codice JavaScript in esecuzione sulla stessa origin.

Attualmente, questo contenuto sensibile viene semplicemente allegato al DOM una volta esportato, rendendolo completamente accessibile a tutte le entità in esecuzione nella stessa app. Cioè, sezioni del codice che non dovrebbero avere accesso alla chiave privata potrebbero estrarla facilmente in chiaro, purché il codice malintenzionato abbia accesso al DOM.
Ma stai tranquillo. Crediamo che questo sia un problema risolvibile 👇
LavaDome attualmente supporta Vanilla JavaScript e React (con altri in arrivo)
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} />
</>;
}
Oltre al nodo radice, tutti i costruttori accettano un secondo argomento opzionale per le opzioni:```javascript // javascript new LavaDomeJavaScript(root, { // boolean unsafeOpenModeShadow: false, });
// react function Secret({ text }) { const {token} = toLavaDomeCapabilities(text); return <LavaDomeReact token={token} // boolean unsafeOpenModeShadow={false} /> }
### Utilizzo Sicuro
A causa delle limitazioni del web core, per integrare LavaDome in modo sicuro, ci sono alcune cose da tenere a mente che richiedono un impegno attivo da parte dello sviluppatore che integra il programma:
#### Ordine di esecuzione
LavaDome, come qualsiasi altro software di sicurezza JavaScript, è sempre vulnerabile al codice che viene eseguito prima di esso.
Ciò significa che, tranne che per il codice di cui ci fidiamo assolutamente, LavaDome deve essere il primo pezzo di codice a essere caricato nel programma dell'applicazione web.
Anche se questo non significa che lo sviluppatore debba usarlo immediatamente (ma solo quando ne ha bisogno), deve comunque includere il programma il prima possibile.
Per farlo correttamente (in sicurezza), deve essere la prima dichiarazione import/require nell'intero programma:```javascript
import '@lavamoat/lavadome-react';
import 'other-stuff';
console.log('Program starts here');
In questo modo garantiamo che LavaDome possa prepararsi per un utilizzo sicuro.
Nota che questo vale analogamente anche per il resto dei pacchetti LavaDome e non solo per @lavamoat/lavadome-react (quindi importarne più di uno non è necessario).
Vai a Security(defensive-coding) per saperne di più.
A causa degli attacchi side-channel e delle limitazioni del web, l'importazione di font remoti può essere una tecnica efficace contro LavaDome. Poiché è incorporata nei meandri del CSS, affrontare questo problema tramite LavaDome non è attualmente possibile.
Fortunatamente, questo può essere affrontato efficacemente utilizzando la direttiva font-src del CSP.
Per mitigare questa forma di attacco, assicurati che la tua applicazione web non consenta di scaricare font da server sconosciuti.
Vai a Security(side-channeling) per saperne di più.
Il testo fornito a LavaDome dallo sviluppatore deve essere imprevedibile al 100%, altrimenti può essere attaccato e divulgato.
Quindi se la tua app deve mostrare "your key is 234789", significa che la tua struttura DOM dovrebbe essere:```html
your key is 234789
e non deve essere:```html
<span> <lavadome>your key is 234789</lavadome> </span>
Vai a Security(findability) per saperne di più.
Integrare LavaDome può essere complicato nel contesto dei test, poiché LavaDome fa un ottimo lavoro nel nascondere il segreto, nascondendolo molto bene anche ai tuoi test!
Per integrare con successo LavaDome nel tuo ambiente di test, potresti aver bisogno di un aiuto da LavaDomeDebug, che viene esportato da @lavamoat/lavadome-core:```javascript
// IMPORT/USE FOR TESTING/DEBUGGING PURPOSES ONLY - NEVER IN PRODUCTION!
import { LavaDomeDebug } from '@lavamoat/lavadome-core';
Ecco alcuni dei metodi di utilità di debug esportati da `LavaDomeDebug` che possono aiutarti a testare i componenti basati su `LavaDome`:
#### `getTextByRoot()`
Data una root a cui è collegato `LavaDome`, `getTextByRoot()` estrae e ricostruisce ricorsivamente il segreto interno. Per consentire ciò, l'istanza di `LavaDome` deve essere inizializzata originariamente con l'opzione UNSAFE `@unsafeOpenModeShadow`, che rende accessibili dall'esterno le shadow interne di `LavaDome`.
Naturalmente, questa è una scelta UNSAFE e rende `LavaDome` completamente vulnerabile, ma ha senso solo per scopi di test/debugging: assicurati di non abilitare mai questa opzione in produzione!```javascript
new LavaDomeJavaScript(root, {
unsafeOpenModeShadow: isThisTestingEnv, // boolean
}).text('123456');
LavaDomeDebug.getTextByRoot(root) === '123456'; // true
stripDistractionFromText()