Ogni piattaforma di successo raggiunge un punto in cui deve consentire ad altri di scrivere il codice che viene eseguito al suo interno. Plug-in utente, funzioni client aziendali personalizzate, estensioni partner, regole aziendali inviate tramite API. Il problema è sempre lo stesso: come fai a eseguire codice che non hai scritto tu, sull'infrastruttura che controlli, senza trasformare quell'apertura in una vulnerabilità? Le risposte tradizionali sono costose, lente o fragili. WebAssembly offre una risposta diversa e per capire il motivo è necessario capire cosa rende difficile il problema.
Perché le soluzioni tradizionali non sono scalabili
Il primo tentativo di molti team è eval() o equivalente: eseguire la stringa di codice direttamente in fase di runtime. È veloce da implementare e catastrofico da mantenere. Il codice del plugin ha accesso a tutto ciò che ha il processo host: memoria, rete, file system. Un plug-in dannoso o semplicemente difettoso può interrompere l'intero processo o esfiltrare dati da altri tenant.
Il secondo tentativo è un microservizio plugin: ogni estensione viene eseguita in un contenitore isolato. Funziona dal punto di vista della sicurezza, ma il costo operativo cresce linearmente con il numero di plugin. Mantenere un contenitore per client non è fattibile su piattaforme con centinaia di estensioni. La latenza di ogni chiamata tra contenitori penalizza inoltre le operazioni che dovrebbero essere inferiori al millisecondo.
I processi secondari con spazi dei nomi Linux sono un'altra opzione: più leggeri dei contenitori, ma con il sovraccarico di inizializzazione e la complessità di seccomp e cgroups per garantire un vero isolamento. Richiede un team che comprenda profondamente il modello del kernel. Il problema comune a tutti questi approcci è che trattano l’isolamento come qualcosa di esterno: si costruisce un recinto attorno al codice non affidabile utilizzando i meccanismi del sistema operativo. Wasm inverte questa logica.
Il modello delle capacità: zero per impostazione predefinita
Un modulo WebAssembly inizia con zero funzionalità. Letteralmente nessuno. Non riesce ad aprire un file. Impossibile effettuare una richiesta di rete. Impossibile leggere le variabili di ambiente. Non può accedere ad alcun byte al di fuori della propria memoria lineare. Se il modulo tenta una di queste operazioni senza che l'host abbia reso esplicitamente disponibile l'interfaccia corrispondente, l'operazione fallisce, non in fase di esecuzione con un'eccezione, ma strutturalmente, perché la funzione chiamata dal modulo semplicemente non esiste nell'ambiente di esecuzione.
Questa si chiama sicurezza basata sulle capacità ed è concettualmente diversa dal modello di autorità ambientale ereditato dal codice nativo. Quando carichi una libreria nativa, viene eseguita con privilegi di processo completi. Quando carichi un modulo Wasm, questo si avvia senza alcun privilegio e tu, come host, decidi cosa consegnare.
L'interfaccia di sicurezza si trova nel codice di integrazione dell'host. Esponi al modulo esattamente le funzioni che hanno senso: accesso all'API Canvas Figma, ma non al file system; accesso ai dati degli ordini Shopify, ma non a databasecredenziali. Il modulo fa tutto ciò che gli hai permesso di fare e niente di più. La superficie di attacco è dichiarata esplicitamente, non dedotta.
Come lo utilizzano le piattaforme reali
Figma è l'esempio più noto. Il sistema di plug-in esegue ciascun plug-in all'interno di una sandbox Wasm. Il plugin riceve l'accesso all'API canvas – può leggere e modificare elementi, creare livelli, accedere alle proprietà del testo – ma non ha accesso a nulla al di fuori di quel contratto. Un plugin non può leggere i file del sistema operativo o effettuare chiamate di rete arbitrarie. Questa non è una politica di utilizzo; È un'impossibilità tecnica. Ecco perché puoi installare un plugin Figma da uno sviluppatore sconosciuto con ragionevole certezza che non esfiltrerà i tuoi file.
Shopify ha preso una decisione simile a Shopify Functions: la logica personalizzata per sconti, convalida del carrello e regole di spedizione viene inviata dai commercianti come moduli Wasm. Ogni invocazione riceve i dati della richiesta, viene eseguita entro rigorosi limiti di CPU e memoria per chiamata e restituisce il risultato. Un commerciante con un codice scritto male non blocca la piattaforma né accede ai dati di altri commercianti.
Envoy Proxy utilizza lo stesso modello per i filtri di traffico personalizzati. Le aziende che utilizzano Envoy come proxy (Istio e AWS App Mesh ne sono esempi) possono scrivere filtri Wasm che elaborano richieste e risposte in transito. Il filtro ha accesso alle intestazioni e al corpo, ma non ha accesso allo stato interno del proxy. Estendibilità senza aprire il nucleo del sistema. I motori di gioco sono arrivati allo stesso modello attraverso percorsi indipendenti: i sistemi di modding che consentono ai giocatori di aggiungere contenuti devono eseguire codice di estranei senza compromettere il gioco host, e Wasm risolve questo problema con lo stesso meccanismo di funzionalità.
Il costo per chi scrive plugin
Questa sicurezza ha un prezzo. Scrivere un plugin per una piattaforma basata su Wasm è più difficile che scrivere JavaScript o Python.
Il primo problema è la toolchain: la compilazione per Wasm richiede un compilatore compatibile: Rust e C/C++ hanno un supporto maturo, Go ha un supporto sperimentale, Python e Ruby arrivano con limitazioni. Il secondo è l’accesso al sistema: all’interno della sandbox non c’è accesso diretto a nient’altro oltre a ciò che l’host ha esposto. Le librerie che effettuano chiamate HTTP dirette non funzionano se l'host non ha reso disponibile l'interfaccia corrispondente. Ciò impone una disciplina di progettazione che all’inizio può essere frustrante.
Lato piattaforma, la complessità sta nel definire bene le API esposte al modulo. Un'API mal progettata è troppo restrittiva (i plug-in non fanno ciò di cui hanno bisogno) o troppo permissiva, compromettendo la sicurezza. Questo contratto riguarda il prodotto e la sicurezza tanto quanto l'ingegneria.
##Quando conviene investire in questo modello
La decisione ha un profilo chiaro. Ha senso quando stai costruendo una piattaforma con sviluppatori esterni di cui non puoi garantire la qualità del codice. Ha senso quando è necessaria la personalizzazione per tenant con limiti di risorse individuali: ogni client ha la propria logica, ma nessuno monopolizza CPU o memoria. Ha senso quando distribuisci codice che verrà eseguito su un'infrastruttura che non controlli completamente.
Non ha senso quando i plugin sono interni e ti fidi del team che li scrive. Il sovraccarico della toolchain e i vincoli del sistema creano un vero e proprio attrito senza eguali quando la minaccia che desideri mitigare non esiste nel tuo modello. La conclusione è questa: l'estensibilità verso l'esterno, verso un pubblico che non controlli, è ciò che Wasm offre.
Leggi anche
- Infrastrutture critiche e dipendenza energetica: cosa devono sapere i manager
- Preparazione quantistica per i leader: cosa fare (e non fare) adesso
- WebAssembly e componenti portabili: la promessa del modello a componenti
- WebAssembly al limite: perché è importante iniziare in modo rapido e isolato
- WebAssembly per leader: quando vale la pena scegliere l'architettura
- Autenticazione dell'applicazione: guida completa alla sicurezza e all'UX