Il web è una piattaforma per applicazioni davvero unica. Le app create su questa piattaforma sono immediatamente accessibili su qualsiasi sistema operativo senza modifiche al codice o compilazione. Ogni volta che un utente accede alla tua app, ha sempre a disposizione la versione più aggiornata. Sono installabili e possono funzionare offline, sono altamente capaci e super condivisibili con un semplice link. Crea un'applicazione web e funziona ovunque.
Poiché il web mira a essere sicuro e protetto per impostazione predefinita, il suo modello di sicurezza deve essere molto conservativo. Qualsiasi nuova funzionalità aggiunta deve essere sicura per un utente occasionale che potrebbe imbattersi accidentalmente tramite un URL. Chiamiamo questo modello di sicurezza drive by web. Sebbene questo sia ideale per molte applicazioni e possa essere reso più sicuro utilizzando norme di sicurezza dei contenuti e isolamento cross-origin, non funziona per tutti i casi d'uso. Una serie di API molto importanti e potenti, come Direct Sockets e Controlled Frame, di cui gli sviluppatori hanno bisogno, non possono essere rese sufficientemente sicure per l'unità tramite il web.
Per queste applicazioni, al momento non esiste un'opzione per la creazione sul web. Per altri, il modello di sicurezza del web potrebbe non essere sufficientemente conservativo; potrebbero non condividere l'ipotesi che il server sia attendibile e preferire invece applicazioni autonome con controllo della versione e firma discreti. È necessario un nuovo modello di sicurezza ad alta affidabilità. Le app web isolate (IWA) forniscono un modello di applicazione isolato, in bundle, con controllo delle versioni, firmato e attendibile basato sulla piattaforma web esistente per consentire a questi sviluppatori.
Uno spettro di fiducia sul web
Puoi pensare alla sicurezza e alle funzionalità sul web in termini di spettro.

Il drive-by web, a sinistra, ha il modello di sicurezza con il livello di attendibilità più basso perché deve essere il più accessibile e quindi ha il minor accesso al sistema di un utente. Le app web installate nel browser, al centro, ottengono un po' più di fiducia e possono integrarsi un po' più in profondità nel sistema di un utente. In genere, gli utenti possono passare dalle versioni web delle app alle versioni installate nel browser senza problemi.
Poi ci sono le applicazioni web isolate ad alta affidabilità.
Hanno l'aspetto e il funzionamento di app native e possono accedere a integrazioni profonde del sistema e a funzionalità avanzate. Gli utenti non possono passare da una all'altra e al drive-by-web. Se hai bisogno di questo livello di sicurezza o di queste funzionalità, non potrai tornare indietro.
Quando cerchi di decidere a quale punto di questo spettro devi puntare, scegli il modello di sicurezza con il livello di attendibilità più basso possibile, ad esempio un'app web progressiva. In questo modo avrai la massima copertura, dovrai gestire il minor numero di problemi di sicurezza e sarà la soluzione più flessibile per i tuoi sviluppatori e utenti.
Secure-by-design
Le app web isolate forniscono un modello di sicurezza altamente attendibile per le applicazioni web. Per attivarla, però, è necessario rivedere alcune delle ipotesi che la navigazione sul web fa in merito all'affidabilità. I componenti di base del web, come server e DNS, non possono più essere considerati attendibili in modo esplicito. I vettori di attacco che potrebbero sembrare più pertinenti per le app native diventano improvvisamente importanti. Pertanto, per accedere al nuovo modello di sicurezza ad alta affidabilità fornito dalle IWA, le app web devono essere pacchettizzate, isolate e protette.
Confezionato
Le pagine e gli asset per le app web isolate non possono essere pubblicati da server live o
recuperati tramite la rete come le normali applicazioni web. Per accedere al nuovo modello di sicurezza ad alta affidabilità, le app web devono invece raggruppare tutte le risorse necessarie per l'esecuzione in un bundle web firmato. I bundle web firmati prendono tutte le risorse necessarie per eseguire un sito e le raggruppano in un file .swbn, concatenandole con un blocco di integrità.
Ciò consente di scaricare in modo sicuro l'intera app web e persino
di condividerla o installarla offline.
Tuttavia, questo pone un problema per la verifica dell'autenticità del codice di un sito: le chiavi TLS richiedono una connessione a internet per funzionare. Invece delle chiavi TLS, gli IWA sono firmati con una chiave che può essere conservata in modo sicuro offline. La buona notizia è che, se riesci a raccogliere tutti i file di produzione in una cartella, puoi trasformarla in un IWA senza molte modifiche.
Generare le chiavi di firma
Le chiavi di firma sono coppie di chiavi Ed25519 o ECDSA P-256, con la chiave privata utilizzata per firmare il bundle e la chiave pubblica utilizzata per verificarlo. Puoi utilizzare OpenSSL per generare e criptare una chiave Ed25519 o ECDSA P-256:
# Generate an unencrypted Ed25519 key
openssl genpkey -algorithm Ed25519 -out private_key.pem
# or generate an unencrypted ECDSA P-256 key
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem
# Encrypt the generated key. This will ask for a passphrase, make sure to use a strong one
openssl pkcs8 -in private_key.pem -topk8 -out encrypted_key.pem
# Delete the unencrypted key
rm private_key.pem
Le chiavi di firma hanno anche uno scopo secondario. Poiché un dominio potrebbe essere vulnerabile
alla perdita di controllo come un server, non può essere utilizzato per identificare l'IWA
installata. Un'IWA viene invece identificata dalla chiave pubblica del bundle, che fa parte della sua firma ed è associata alla chiave privata. Si tratta di una modifica significativa al funzionamento del web drive-by, pertanto, anziché utilizzare HTTPS, le IWA utilizzano anche un nuovo schema: isolated-app://.
Raggruppare l'app
Ora che hai la chiave di firma, è il momento di creare il bundle della tua app web. Per farlo, puoi utilizzare i pacchetti NodeJS ufficiali per creare il bundle e poi firmare le IWA (sono disponibili anche gli strumenti a riga di comando Go). Per prima cosa, utilizza il pacchetto wbn, che punta alla cartella contenente tutti i file di produzione della tua IWA (qui dist) per raggrupparli in un bundle non firmato:
npx wbn --dir dist
In questo modo verrà generato un bundle web non firmato della directory in out.wbn. Una volta
generato, utilizza la chiave Ed25519 o ECDSA P-256 criptata che hai creato in precedenza
per firmarlo utilizzando wbn-sign:
npx wbn-sign -i out.wbn -k encrypted_key.pem -o signed.swbn
Verrà generato un bundle web firmato dal bundle web non firmato denominato
signed.swbn. Una volta firmato, lo strumento restituirà anche l'ID pacchetto web e l'origine dell'app web isolata. L'origine dell'app web isolata è il modo in cui la tua IWA
viene identificata nel browser.
Web Bundle ID: ggx2sheak3vpmm7vmjqnjwuzx3xwot3vdayrlgnvbkq2mp5lg4daaaic
Isolated Web App Origin: isolated-app://ggx2sheak3vpmm7vmjqnjwuzx3xwot3vdayrlgnvbkq2mp5lg4daaaic/
Se utilizzi Webpack, Rollup o uno strumento che supporta i relativi plug-in (come Vite), puoi utilizzare uno dei plug-in bundler (Webpack, Rollup) che racchiudono questi pacchetti anziché chiamarli direttamente. In questo modo verrà generato un bundle firmato come output della build.
Testa la tua app
Puoi testare la tua IWA in due modi: eseguendo il server di sviluppo tramite il proxy di sviluppo IWA integrato di Chrome o installando l'IWA in bundle. Per farlo, devi utilizzare Chrome o ChromeOS 120 o versioni successive, attivare i flag IWA e installare l'app tramite Web App Internals di Chrome:
- Attivare il flag
chrome://flags/#enable-isolated-web-app-dev-mode - Testa la tua IWA andando alla pagina Internals dell'app web di Chrome all'indirizzo
chrome://web-app-internals
Una volta nella pagina Internals dell'app web, hai due opzioni: Install IWA with Dev
Mode Proxy o Install IWA from Signed Web Bundle.
Se esegui l'installazione tramite un proxy in modalità sviluppatore, puoi installare qualsiasi URL, inclusi i siti in esecuzione da un server di sviluppo locale, come IWA, senza raggrupparli, a condizione che soddisfino gli altri requisiti di installazione delle IWA. Una volta installata, al sistema verrà aggiunta un'IWA per l'URL con le corrette norme di sicurezza e limitazioni in vigore e l'accesso alle API solo per le IWA. Verrà assegnato un identificatore casuale. In questa modalità sono disponibili anche gli strumenti di sviluppo di Chrome per aiutarti a eseguire il debug dell'applicazione. Se esegui l'installazione da un Signed Web Bundle, caricherai l'IWA firmata e in bundle e verrà installata come se fosse stata scaricata da un utente finale.
Nella pagina Internals dell'app web, puoi anche forzare i controlli degli aggiornamenti per qualsiasi applicazione installata tramite il proxy della modalità sviluppatore o da un pacchetto web firmato per testare anche la procedura di aggiornamento.
Isolamento
L'attendibilità è fondamentale per le app web isolate. A partire dal modo in cui corrono. Gli utenti hanno modelli mentali diversi per ciò che un'app può e deve fare a seconda che venga eseguita in un browser o in una finestra autonoma, in genere ritenendo che le app autonome abbiano più accesso e siano più potenti. Poiché le IWA possono accedere ad API ad alta affidabilità, devono essere eseguite in una finestra autonoma per allinearsi a questo modello mentale. In questo modo, vengono separati visivamente dal browser. Ma va oltre la semplice separazione visiva.
Le app web isolate vengono eseguite su un protocollo separato rispetto ai siti web nel browser
(isolated-app anziché http o https). Ciò significa che ogni IWA è completamente separata
dai siti web eseguiti nel browser, anche se sono creati dalla stessa azienda,
grazie alle
norme relative alla stessa origine.
Anche lo spazio di archiviazione IWA è separato. Insieme, ciò garantisce che
i contenuti cross-origin non possano essere divulgati tra diverse IWA o tra
le IWA e il normale contesto di navigazione di un utente.
Tuttavia, né l'isolamento né il raggruppamento e la firma del codice di un sito sono utili per stabilire l'affidabilità se un'IWA può scaricare ed eseguire codice arbitrario dopo l'installazione. Per garantire questo, consentendo comunque alle IWA di connettersi ad altri siti per i contenuti, le IWA applicano un rigoroso insieme di Content Security Policy:
- Consente solo JavaScript dal bundle, ma consente l'esecuzione di Wasm indipendentemente dalla sua origine.
(
script-src) - Consente a JavaScript di recuperare dati da domini cross-origin sicuri e non localhost, connettersi a endpoint WebSocket e WebTransport e a URL blob e data (
connect-src). - Protegge dagli attacchi di injection di cross-site scripting (XSS) DOM regolando la modalità di utilizzo delle funzioni di manipolazione del DOM (
require-trusted-types-for). - Consente frame, immagini, audio e video da qualsiasi dominio HTTPS
(
frame-src,img-src,media-src) - Consente i caratteri del bundle e i blob
(
font-src) - Consenti CSS in linea o CSS dal bundle
(
style-src) - Gli elementi
<object>,<embed>e<base>non possono essere utilizzati (object-srcebase-uri) - Consente solo le risorse del bundle per qualsiasi
altra richiesta coperta da CSP
(
default-src)
Content-Security-Policy: script-src 'self' 'wasm-unsafe-eval';
connect-src 'self' https: wss: blob: data:;
require-trusted-types-for 'script';
frame-src 'self' https: blob: data:;
img-src 'self' https: blob: data:;
media-src 'self' https: blob: data:;
font-src 'self' blob: data:;
style-src 'self' 'unsafe-inline';
object-src 'none';
base-uri 'none';
default-src 'self';
Questi CSP non sono sufficienti per proteggere completamente dal codice di terze parti potenzialmente dannoso. Inoltre, le app web installabili sono isolate tra origini diverse, impostando le intestazioni per ridurre la capacità delle risorse di terze parti di influire su di esse:
- Consenti solo le risorse del bundle o le risorse multiorigine contrassegnate esplicitamente
come supporto
CORS con un'intestazione
di policy per le risorse multiorigine (CORP) impostata o l'attributo
crossorigin. (Cross-Origin-Embedder-Policy) - Non consentire le richieste multiorigine senza CORS
(
Cross-Origin-Resource-Policy) - Isola il contesto di navigazione dai documenti multiorigine,
impedendo i riferimenti window.opener e l'accesso agli oggetti globali
(
Cross-Origin-Opener-Policy) - Impedire l'incorporamento del sito all'interno di un frame o iframe
(CSP,
frame-ancestors)
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
Content-Security-Policy: frame-ancestors 'self'
Anche con queste limitazioni in vigore, esiste un altro potenziale attacco
contro cui le IWA si proteggono: gli attacchi di interruzione della sequenza. Un attacco di interruzione della sequenza
si verifica quando contenuti dannosi di terze parti tentano di creare un'esperienza utente confusa e
potenzialmente sfruttabile navigando in una pagina in modo inaspettato, ad esempio navigando direttamente a una pagina delle impostazioni interne. Le IWA impediscono questo comportamento
non consentendo il deep linking arbitrario da siti esterni, ma solo l'apertura
delle applicazioni tramite la navigazione verso punti di accesso ben definiti, come un
start_url,
un gestore
di protocolli, una destinazione
di condivisione o tramite un gestore
di avvio.
Bloccato
Il packaging e l'isolamento forniscono una serie di garanzie su ciò che è consentito eseguire e sulla sua origine, ma la natura dinamica delle autorizzazioni sul web significa che da sole non possono garantire che un'applicazione web utilizzi solo le funzionalità di cui ha bisogno. Poiché funzionalità diverse hanno considerazioni di sicurezza diverse, un utente o un amministratore vorrà controllare quali autorizzazioni può utilizzare un'app web installabile, proprio come può fare con altre app native come Android e iOS prima di installare o aggiornare un'app.
Per facilitare questa operazione, le app web isolate bloccano per impostazione predefinita tutte le richieste di autorizzazione.
Gli sviluppatori possono quindi attivare l'autorizzazione di cui hanno bisogno aggiungendo un
campo permissions_policy al manifest dell'app web. Questo campo contiene
coppie chiave/valore di direttive
della norma relativa alle autorizzazioni
e liste consentite
della norma relativa alle autorizzazioni
per ogni autorizzazione che l'IWA, o qualsiasi frame secondario come un frame controllato o un
iframe, può richiedere. L'aggiunta di un'autorizzazione qui non la concede automaticamente;
al contrario, la rende disponibile per essere richiesta quando viene effettuata una richiesta per questa funzionalità.
Supponiamo che tu stia creando un'IWA di monitoraggio della flotta come esempio. Potresti aver bisogno dell'IWA per poter richiedere la posizione dell'utente e anche per una mappa incorporata per richiedere la posizione. Potresti anche voler consentire a qualsiasi sito incorporato di passare alla modalità a schermo intero per offrire una visualizzazione immersiva all'utente. Per farlo, configura la seguente policy delle autorizzazioni nel file manifest dell'app web:
"permissions_policy": {
"geolocation": [ "self", "https://map.example.com" ],
"fullscreen": [ "*" ]
}
Poiché anche i WebBundle possono specificare le intestazioni Permissions Policy, saranno consentite solo le autorizzazioni dichiarate in entrambe e solo le origini nelle liste consentite che si trovano in entrambe.
Con nome e versione
Le normali app web si basano sul proprio nome di dominio per identificarsi agli utenti e possono essere aggiornate modificando il codice pubblicato in quel dominio. Tuttavia, a causa dei vincoli di sicurezza relativi alle app web isolate, l'identità e gli aggiornamenti devono essere gestiti in modo diverso. Proprio come le app web progressive, le app web isolate hanno bisogno di un file manifest dell'app web per identificarsi agli utenti.
Manifest dell'app web
Le app web isolate condividono le stesse proprietà chiave del manifestper il manifest
dell'app web delle PWA, con alcune piccole variazioni. Ad esempio, display
funziona in modo leggermente diverso: sia browser che minimal-ui vengono forzati in una
visualizzazione minimal-ui, mentre fullscreen e standalone vengono forzati in una
visualizzazione standalone (le opzioni display_override aggiuntive funzionano come previsto).
Inoltre, devono essere inclusi altri due campi, version e
update_manifest_url:
version: obbligatorio per le app web isolate. Una stringa composta da uno o più numeri interi separati da un punto (.). La versione può essere semplice, ad esempio1,2,3e così via, oppure complessa, ad esempio SemVer (1.2.3). Il numero di versione deve corrispondere all'espressione regolare^(\d+.?)*\d$.update_manifest_url: campo facoltativo, ma consigliato, che punta a un URL HTTPS (olocalhostper i test) da cui è possibile recuperare un file manifest di aggiornamento dell'applicazione web.
Un manifest dell'app web minimo per un'app web isolata potrebbe avere un aspetto simile a questo:
{
"name": "IWA Kitchen Sink",
"version": "0.1.0",
"update_manifest_url": "https://example.com/updates.json",
"start_url": "/",
"icons": [
{
"src": "/images/icon.png",
"type": "image/png",
"sizes": "512x512",
"purpose": "any"
},
{
"src": "/images/icon-mask.png",
"type": "image/png",
"sizes": "512x512",
"purpose": "maskable"
}
]
}
Manifest di aggiornamento dell'applicazione web
Un manifest di aggiornamento dell'applicazione web è un file JSON che descrive ogni versione di
una determinata applicazione web. L'oggetto JSON contiene un campo obbligatorio, version, che è un elenco di oggetti contenenti version, src e channels:
version- Il numero di versione dell'applicazione, uguale al campoversiondel manifest dell'app websrc: l'URL HTTPS (olocalhostper i test) che rimanda al bundle ospitato per quella versione (il file.swbn). Gli URL relativi sono relativi al file manifest di aggiornamento dell'applicazione web.channels- Un elenco di stringhe per identificare il canale di aggiornamento a cui appartiene questa versione. Un canaledefaultspeciale viene utilizzato per descrivere il canale principale che verrà utilizzato se non viene selezionato nessun altro canale.
Puoi anche includere un campo channels, un oggetto degli ID canale con una proprietà name facoltativa per ogni ID per fornire un nome leggibile (incluso per il canale default). Un canale che non include la proprietà name o che non è incluso nell'oggetto channels utilizza il proprio ID come nome.
Un manifest di aggiornamento minimo potrebbe avere il seguente aspetto:
{
"versions": [
{
"version": "5.2.17",
"src": "https://cdn.example.com/app-package-5.2.17.swbn",
"channels": ["next", "5-lts", "default"]
},
{
"version": "5.3.0",
"src": "v5.3.0/package.swbn",
"channels": ["next", "default"]
},
{
"version": "5.3.1",
"src": "v5.3.1/package.swbn",
"channels": ["next"]
},
],
"channels": {
"default": {
"name": "Stable"
},
"5-lts": {
"name": "5.x Long-term Stable"
}
}
}
In questo esempio, ci sono tre canali: default che verrà etichettato
Stable, 5-lts che verrà etichettato 5.x Long-term Stable e next che
verrà etichettato next. Se un utente utilizza il canale 5-lts, riceverà la versione
5.2.17, se utilizza il canale default riceverà la versione 5.3.0 e se
utilizza il canale next riceverà la versione 5.3.1.
I manifest di aggiornamento delle applicazioni web possono essere ospitati su qualsiasi server. Gli aggiornamenti vengono controllati ogni 4-6 ore.
Gestita dall'amministratore
Per il lancio iniziale, le app web isolate potranno essere installate solo su Chromebook gestiti con Chrome Enterprise da un amministratore tramite il pannello di amministrazione.
Per iniziare, nel pannello di amministrazione, vai a Dispositivi > Chrome > App ed
estensioni > Utenti e browser. Questa scheda ti consente di aggiungere app ed estensioni
dal Chrome Web Store, da Google Play e dal web per gli utenti della tua
organizzazione. Per aggiungere elementi, apri il pulsante giallo mobile Aggiungi (+)
nell'angolo in basso a destra dello schermo e seleziona il tipo di elemento
da aggiungere.
Quando viene aperto, viene visualizzata un'icona di un quadrato all'interno di un altro quadrato, con l'etichetta Aggiungi un'app web isolata. Se fai clic su questa icona, si apre una finestra modale per aggiungere un'app web isolata alla tua unità organizzativa. Per farlo, avrai bisogno di due informazioni: l'ID pacchetto web dell'IWA (generato dalla chiave pubblica dell'app e visualizzato dopo che l'app è stata raggruppata e firmata) e l'URL del manifest di aggiornamento dell'app web per l'IWA. Una volta installato, avrai a disposizione il set standard di opzioni del pannello di amministrazione per gestirlo:
- Criterio di installazione: come vuoi che venga installata l'app web installabile, ovvero forzata l'installazione, forzata l'installazione e bloccata sullo scaffale di ChromeOS o impedita l'installazione.
- Avvia all'accesso: come vuoi che venga avviata l'IWA. Puoi consentire a un utente di avviarla manualmente, forzare l'avvio dell'IWA quando l'utente esegue l'accesso, ma consentirgli di chiuderla oppure forzare l'avvio quando l'utente esegue l'accesso e impedirne la chiusura.
Una volta salvata, l'app verrà installata la volta successiva che viene applicato un aggiornamento dei criteri ai Chromebook nell'unità organizzativa. Una volta installato, il dispositivo di un utente controllerà gli aggiornamenti dal file manifest di aggiornamento dell'app web ogni 4-6 ore.
Oltre a forzare l'installazione delle IWA, puoi anche concedere automaticamente alcune autorizzazioni
in modo simile a quanto puoi fare per altre applicazioni web. Per farlo, vai a
Dispositivi > Chrome > Funzionalità web e fai clic sul pulsante Aggiungi origine. In
Origin / site pattern field, incolla l'ID pacchetto web dell'IWA
(isolated-app:// verrà aggiunto automaticamente come protocollo). Da
qui, puoi impostare i livelli di accesso a diverse API (consentito/bloccato/non impostato),
tra cui la gestione delle finestre, la gestione dei caratteri locali e l'API monitoraggio
dello schermo. Per le API
che potrebbero richiedere l'attivazione da parte di un amministratore, come l'API
di monitoraggio dello schermo obbligatorio, verrà visualizzata una finestra di dialogo aggiuntiva per confermare
la tua selezione. Al termine, salva le modifiche e i tuoi utenti saranno pronti
per iniziare a utilizzare la tua app web ibrida.
Utilizzare le estensioni
Sebbene le app web isolate non funzionino con le estensioni pronte all'uso, puoi
collegare le estensioni di tua proprietà. Per farlo, devi modificare il file manifest dell'estensione. La sezione externally_connectable del file manifest
definisce con quali pagine web esterne o altre estensioni di Chrome la tua estensione può
interagire. Aggiungi l'origine della tua IWA nel campo matches all'interno di
externally_connectable (assicurati di includere lo schema isolated-app://):
{
"externally_connectable": {
"matches": ["isolated-app://79990854-bc9f-4319-a6f3-47686e54ed29/*"]
}
}
In questo modo, l'estensione potrà essere eseguita nell'app web isolata, ma non potrà inserirvi contenuti. Potrai solo trasferire messaggi tra l'estensione e l'app web isolata.