A Web é uma plataforma de aplicativos verdadeiramente única. Os apps criados nele ficam instantaneamente acessíveis em qualquer sistema operacional sem necessidade de alterações no código ou compilação. Sempre que um usuário acessa seu app, ele tem a versão mais atualizada. Eles são instaláveis e podem funcionar off-line, são altamente capazes e fáceis de compartilhar com apenas um link. Crie um aplicativo da Web, e ele vai funcionar em qualquer lugar.
Como a Web pretende ser segura por padrão, o modelo de segurança precisa ser muito conservador. Todas as novas funcionalidades adicionadas precisam ser seguras para que um usuário casual não as encontre acidentalmente por um URL. Chamamos esse modelo de segurança de drive-by web. Embora isso seja ótimo para muitos aplicativos e possa ser mais seguro usando políticas de segurança de conteúdo e isolamento entre origens, não funciona para todos os casos de uso. Várias APIs muito importantes e poderosas, como Sockets diretos e Frame controlado, que os desenvolvedores precisam, não podem ser protegidas o suficiente para o drive pela Web.
No momento, esses aplicativos não têm uma opção para criar na Web. Para outros, o modelo de segurança da Web pode não ser conservador o suficiente. Eles podem não compartilhar a premissa de que o servidor é confiável e preferir aplicativos autônomos discretamente versionados e assinados. É necessário um novo modelo de segurança de alta confiança. Os apps isolados da Web (IWAs) oferecem um modelo de aplicativo isolado, agrupado, com versão, assinado e confiável criado na plataforma da Web atual para permitir que esses desenvolvedores trabalhem.
Um espectro de confiança na Web
Pense na segurança e nos recursos da Web como um espectro.

A Web de acesso rápido, à esquerda, tem o modelo de segurança de confiança mais baixo porque precisa ser mais acessível e, portanto, tem menos acesso ao sistema de um usuário. Os apps da Web instalados no navegador, no meio, ganham um pouco mais de confiança e podem se integrar um pouco mais profundamente ao sistema de um usuário. Em geral, os usuários podem alternar entre versões da Web de apps e versões instaladas no navegador sem problemas.
Depois, há os aplicativos da Web isolados de alta confiança.
Eles agem e parecem mais apps nativos e podem acessar integrações profundas do sistema e recursos avançados. Os usuários não podem alternar entre eles e o drive-by-web. Se você precisar desse nível de segurança ou desses recursos, não será possível voltar atrás.
Ao tentar decidir qual ponto desse espectro você deve buscar, use o modelo de segurança de menor confiança possível, como um Progressive Web App (PWA). Isso vai oferecer o maior alcance, exigir que você gerencie a menor quantidade de problemas de segurança e será o mais flexível para seus desenvolvedores e usuários.
Segurança incorporada ao design
Os apps isolados da Web oferecem um modelo de segurança altamente confiável para aplicativos da Web. No entanto, para ativar isso, algumas das proposições que o drive-by-web faz sobre confiança precisam ser repensadas. Os blocos de construção da Web, como servidores e DNS, não podem mais ser confiáveis explicitamente. Os vetores de ataque que podem parecer mais relevantes para apps nativos de repente se tornam importantes. Portanto, para ter acesso ao novo modelo de segurança de alta confiança fornecido pelas AIWs, os apps da Web precisam ser empacotados, isolados e bloqueados.
Embalado
Páginas e recursos para Apps Isolados da Web não podem ser veiculados de servidores ativos ou
buscados pela rede como aplicativos da Web normais. Em vez disso, para ter acesso
ao novo modelo de segurança de alta confiança, os apps da Web precisam empacotar todos os
recursos necessários para execução em um
Signed WebBundle. Os
pacotes da Web assinados usam todos os recursos necessários para executar um site e os
compactam em um arquivo .swbn, concatenando-os com um bloco de
integridade.
Isso permite que o app da Web seja baixado com segurança por completo e até
compartilhado ou instalado off-line.
No entanto, isso representa um problema para verificar a autenticidade do código de um site: as chaves TLS exigem uma conexão de Internet para funcionar. Em vez de chaves TLS, as IWAs são assinadas com uma chave que pode ser mantida off-line com segurança. A boa notícia é que, se você conseguir reunir todos os arquivos de produção em uma pasta, poderá transformá-la em um IWA sem muitas modificações.
Gerar chaves de assinatura
As chaves de assinatura são pares de chaves Ed25519 ou ECDSA P-256. A chave privada é usada para assinar o pacote, e a chave pública é usada para verificar o pacote. É possível usar o OpenSSL para gerar e criptografar uma chave Ed25519 ou 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
As chaves de assinatura também têm uma finalidade secundária. Como um domínio pode estar vulnerável à perda de controle, como um servidor, ele não pode ser usado para identificar a IWA instalada. Em vez disso, uma IWA é identificada pela chave pública do pacote, que faz parte da assinatura e está vinculada à chave privada. Essa é uma mudança significativa no funcionamento da Web drive-by. Em vez de usar HTTPS, os IWAs usam um novo esquema: isolated-app://.
Agrupar seu app
Com a chave de assinatura disponível, é hora de agrupar seu app da Web. Para isso, você pode usar os pacotes oficiais do NodeJS para agrupar e assinar seus IWAs. As ferramentas de linha de comando do Go também estão disponíveis. Primeiro, use o pacote wbn, apontando para a pasta que contém todos os arquivos de produção do IWA (aqui dist) para agrupá-los em um pacote não assinado:
npx wbn --dir dist
Isso vai gerar um pacote da Web não assinado desse diretório para out.wbn.. Depois
de gerado, use a chave Ed25519 ou ECDSA P-256 criptografada que você criou
para assinar usando wbn-sign:
npx wbn-sign -i out.wbn -k encrypted_key.pem -o signed.swbn
Isso vai gerar um pacote assinado da Web com base no pacote não assinado chamado
signed.swbn. Depois de assinado, a ferramenta também vai gerar o ID do pacote da Web e a origem do
App Isolado da Web. A origem do App Isolado da Web é como seu IWA é
identificado no navegador.
Web Bundle ID: ggx2sheak3vpmm7vmjqnjwuzx3xwot3vdayrlgnvbkq2mp5lg4daaaic
Isolated Web App Origin: isolated-app://ggx2sheak3vpmm7vmjqnjwuzx3xwot3vdayrlgnvbkq2mp5lg4daaaic/
Se você estiver usando Webpack, Rollup ou uma ferramenta que oferece suporte aos plug-ins deles (como Vite), use um dos plug-ins do bundler (Webpack, Rollup) que envolve esses pacotes em vez de chamá-los diretamente. Isso vai gerar um pacote assinado como resultado do build.
Testar o app
Você pode testar seu AIW de duas maneiras: executando o servidor de desenvolvimento pelo proxy de desenvolvedor de AIW integrado do Chrome ou instalando o AIW agrupado. Para isso, você precisa usar o Chrome ou o ChromeOS 120 ou mais recente, ativar as flags de AIW e instalar o app usando o Web App Internals do Chrome:
- Ativar a flag
chrome://flags/#enable-isolated-web-app-dev-mode - Teste sua IWA acessando a página "Internos do app da Web" do Chrome em
chrome://web-app-internals
Na página "Internos do app da Web", você tem duas opções: Install IWA with Dev
Mode Proxy ou Install IWA from Signed Web Bundle.
Se você instalar usando um proxy do modo de desenvolvimento, poderá instalar qualquer URL, incluindo sites executados em um servidor de desenvolvimento local, como um IWA, sem agrupar, presumindo que eles atendam aos outros requisitos de instalação do IWA. Depois de instalado, um IWA para esse URL será adicionado ao seu sistema com as políticas de segurança e restrições corretas, além do acesso a APIs somente de IWA. Ele vai receber um identificador aleatório. O Chrome DevTools também está disponível nesse modo para ajudar você a depurar seu aplicativo. Se você instalar de um pacote da Web assinado, vai fazer upload da IWA assinada e agrupada, e ela será instalada como se tivesse sido baixada por um usuário final.
Na página "Internos do app da Web", também é possível forçar verificações de atualização para qualquer aplicativo instalado pelo proxy do modo de desenvolvedor ou de um pacote da Web assinado para testar o processo de atualização.
Isolamento
A confiança é fundamental para os Apps Isolados da Web. Isso começa com a forma como eles são executados. Os usuários têm modelos mentais diferentes sobre o que um app pode e deve fazer, dependendo se ele está sendo executado em um navegador ou em uma janela independente. Em geral, eles acreditam que os apps independentes têm mais acesso e são mais poderosos. Como IWAs podem acessar APIs de alta confiança, elas precisam ser executadas em uma janela independente para se alinhar a esse modelo mental. Isso os separa visualmente do navegador. Mas vai além da separação visual.
Os Apps Isolados da Web são executados em um protocolo diferente dos sites no navegador
(isolated-app em vez de http ou https). Isso significa que cada IWA é totalmente separado
dos sites executados no navegador, mesmo que sejam criados pela mesma empresa,
graças à
política de mesma origem.
O armazenamento da IWA também é separado. Isso garante que o conteúdo de origem cruzada não vaze entre diferentes IWAs ou entre IWAs e o contexto de navegação normal de um usuário.
No entanto, nem o isolamento nem o agrupamento e a assinatura do código de um site são úteis para estabelecer confiança se uma IWA puder baixar e executar código arbitrário após a instalação. Para garantir isso e ainda permitir que os IWAs se conectem a outros sites para conteúdo, eles aplicam um conjunto rigoroso de políticas de segurança de conteúdo:
- Permite apenas JavaScript do pacote, mas permite que o Wasm seja
executado, seja qual for a origem.
(
script-src) - Permite que o JavaScript busque em domínios seguros de origem cruzada que não sejam localhost, conecte endpoints WebSocket e WebTransport e URLs blob e data (
connect-src). - Protege contra ataques de injeção de script em vários sites (XSS) do DOM ao
regular como as funções de manipulação do DOM podem ser usadas
(
require-trusted-types-for) - Permite frames, imagens, áudio e vídeo de qualquer domínio HTTPS
(
frame-src,img-src,media-src) - Permite fontes do pacote e blobs
(
font-src) - Permitir CSS in-line ou do pacote
(
style-src) - Não é possível usar os elementos
<object>,<embed>e<base>(object-srcebase-uri). - Permite apenas recursos do pacote para qualquer
outra solicitação coberta pela 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';
Essas CSPs não são suficientes para proteger totalmente contra código de terceiros potencialmente malicioso. As IWAs também são isoladas de origem cruzada, definindo cabeçalhos para reduzir a capacidade de recursos de terceiros de afetá-las:
- Permita apenas recursos do pacote ou recursos de origem cruzada explicitamente
marcados como compatíveis com
CORS com um cabeçalho
de política de recursos de origem cruzada (CORP) definido ou o atributo
crossorigin. (Cross-Origin-Embedder-Policy) - Não permitir solicitações entre origens sem CORS
(
Cross-Origin-Resource-Policy) - Isolar o contexto de navegação de documentos de origem cruzada,
impedindo referências window.opener e acesso a objetos globais
(
Cross-Origin-Opener-Policy) - Impedir que o site seja incorporado em um frame ou 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'
Mesmo com essas restrições, há mais um possível ataque que
os IWAs evitam: ataques de quebra de sequência. Um ataque de quebra de sequência
acontece quando um conteúdo malicioso de terceiros tenta criar uma experiência do usuário confusa e
potencialmente explorável navegando até uma página de maneira
inesperada, como ir diretamente para uma página de configurações internas. As IWAs evitam isso ao
proibir links diretos arbitrários de sites externos, permitindo apenas que
aplicativos sejam abertos navegando até pontos de entrada bem definidos, como um
start_url,
um processador de
protocolo, um destino de
compartilhamento ou por um processador de
início.
Bloqueado
O empacotamento e o isolamento oferecem um conjunto de garantias sobre o que pode ser executado e de onde veio, mas a natureza dinâmica das permissões na Web significa que elas sozinhas não podem garantir que um aplicativo da Web esteja usando apenas os recursos de que precisa. Como diferentes recursos têm considerações de segurança diferentes, um usuário ou administrador pode auditar quais permissões uma IWA pode usar, assim como acontece com outros apps nativos, como Android e iOS, antes de instalar ou atualizar um app.
Para facilitar isso, os Apps Isolados da Web bloqueiam todas as solicitações de permissão por padrão.
Os desenvolvedores podem ativar a permissão necessária adicionando um
campo permissions_policy ao manifesto do app da web. Esse campo contém pares de chave/valor de diretivas de política de permissão e listas de permissão de política de permissão para cada permissão que a IWA, ou qualquer frame filho, como um frame controlado ou um iframe, pode solicitar. Adicionar uma permissão aqui não a concede automaticamente. Em vez disso, ela fica disponível para ser solicitada quando um pedido de recurso é feito.
Imagine que você está criando um IWA de rastreamento de frota como exemplo. Talvez seja necessário que sua IWA possa solicitar a localização do usuário, e um mapa incorporado também precisa solicitar a localização. Você também pode querer que qualquer site incorporado possa ser aberto em tela cheia para oferecer uma visualização imersiva ao usuário. Para isso, configure a seguinte política de permissões no manifesto do app da Web:
"permissions_policy": {
"geolocation": [ "self", "https://map.example.com" ],
"fullscreen": [ "*" ]
}
Como os WebBundles também podem especificar cabeçalhos Permissions Policy , apenas as permissões declaradas em ambos serão permitidas, e somente as origens nas listas de permissões que estão em ambos serão permitidas.
Nomeado e com controle de versões
Os apps da Web normais dependem do nome de domínio para se identificar aos usuários e podem ser atualizados mudando o código veiculado nesse domínio. No entanto, devido às restrições de segurança dos Isolated Web Apps, a identidade e as atualizações precisam ser processadas de maneira diferente. Assim como os Progressive Web Apps, os Isolated Web Apps precisam de um arquivo Manifesto do app da Web para serem identificados pelos usuários.
Manifesto do app da Web
Os Apps Isolados da Web compartilham as mesmas propriedades principais do manifesto para o manifesto do app da Web que os PWAs, com algumas pequenas variações. Por exemplo, display funciona um pouco diferente. browser e minimal-ui são forçados a uma exibição minimal-ui, e fullscreen e standalone são forçados a uma exibição standalone. Outras opções de display_override funcionam como esperado.
Além disso, há mais dois campos que precisam ser incluídos, version e update_manifest_url:
version: obrigatório para apps isolados da Web. Uma string que consiste em um ou mais números inteiros separados por um ponto (.). Sua versão pode ser algo simples como1,2,3etc., ou algo complexo como SemVer (1.2.3). O número da versão precisa corresponder à expressão regular^(\d+.?)*\d$.update_manifest_url: opcional, mas recomendado, aponta para um URL HTTPS (oulocalhostpara testes) em que um manifesto de atualização de aplicativo da Web pode ser recuperado.
Um manifesto de app da Web mínimo para um app isolado da Web pode ter esta aparência:
{
"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"
}
]
}
Manifesto de atualização do aplicativo da Web
Um manifesto de atualização de aplicativo da Web é um arquivo JSON que descreve cada versão de
um determinado aplicativo da Web. O objeto JSON contém um campo obrigatório, version, que é uma lista de objetos que contêm version, src e channels:
version: o número da versão do aplicativo, igual ao campoversiondo manifesto do app da Web.src: o URL HTTPS (oulocalhostpara testes) que aponta para o pacote hospedado dessa versão (o arquivo.swbn). Os URLs relativos são relativos ao arquivo de manifesto de atualização do aplicativo da Web.channels: uma lista de strings para identificar o canal de atualização de que esta versão faz parte. Um canaldefaultespecial é usado para descrever o canal principal que será usado se nenhum outro for selecionado.
Você também pode incluir um campo channels, um objeto dos IDs do seu canal com uma propriedade name opcional para cada ID, para fornecer um nome legível por humanos (inclusive para o canal default). Um canal que não inclui a propriedade name ou não está incluído no objeto channels usa o ID como nome.
Um manifesto de atualização mínima pode ter esta aparência:
{
"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"
}
}
}
Neste exemplo, há três canais: default, que será rotulado como Stable, 5-lts, que será rotulado como 5.x Long-term Stable, e next, que será rotulado como next. Se um usuário estiver no canal 5-lts, ele vai receber a versão 5.2.17. Se estiver no canal default, vai receber a versão 5.3.0. Se estiver no canal next, vai receber a versão 5.3.1.
Os manifestos de atualização de aplicativos da Web podem ser hospedados em qualquer servidor. As atualizações são verificadas a cada 4 a 6 horas.
Gerenciado pelo admin
No lançamento inicial, os Apps Isolados da Web só poderão ser instalados em Chromebooks gerenciados pelo Chrome Enterprise por um administrador no painel de administração.
Para começar, no painel de administração, acesse Dispositivos > Chrome > Apps e
extensões > Usuários e navegadores. Nela, você pode adicionar apps e extensões da Chrome Web Store, do Google Play e da Web para usuários em toda a organização. Para adicionar itens, abra o botão amarelo flutuante de adição (+) no canto inferior direito da tela e selecione o tipo de item que você quer adicionar.
Quando aberto, um ícone de um quadrado dentro de um quadrado aparece com o rótulo Adicionar um App Isolado da Web. Clique nele para abrir uma caixa de diálogo modal e adicionar um AIW à sua OU. Para isso, você precisa de duas informações: o ID do pacote da Web do IWA (gerado com base na chave pública do app e exibido depois que o app é agrupado e assinado) e o URL do manifesto de atualização do app da Web para o IWA. Depois de instalado, você terá o conjunto padrão de opções do painel de administração para gerenciar o app:
- Política de instalação: como você quer que a IWA seja instalada, seja forçada, forçada e fixada na plataforma do ChromeOS ou impedida.
- Iniciar ao fazer login: como você quer que a IWA seja iniciada. É possível permitir que um usuário inicie manualmente, forçar a inicialização da IWA quando o usuário faz login, mas permitir que ele feche, ou forçar a inicialização quando o usuário faz login e impedir que ela seja fechada.
Depois de salvo, o app será instalado na próxima vez que uma atualização de política for aplicada aos Chromebooks nessa UO. Depois de instalado, o dispositivo de um usuário verifica se há atualizações do manifesto de atualização do app da Web a cada 4 a 6 horas.
Além de forçar a instalação de IWAs, você também pode conceder automaticamente algumas permissões
para eles de maneira semelhante a outros aplicativos da Web. Para fazer isso, acesse Dispositivos > Chrome > Recursos da Web e clique no botão Adicionar origem. Em
Origin / site pattern field, cole o ID do pacote da Web do IWA
(isolated-app:// será adicionado automaticamente como protocolo). Lá, você pode definir níveis de acesso para diferentes APIs (permitidas/bloqueadas/não definidas), incluindo gerenciamento de janelas, gerenciamento de fontes locais e a API screen
monitoring. Para APIs
que podem exigir ativação adicional por um administrador, como a
API obrigatória de monitoramento de tela, uma caixa de diálogo extra vai aparecer para confirmar
sua seleção. Quando terminar, salve as mudanças. Assim, os usuários poderão começar a usar sua IWA.
Trabalhar com extensões
Embora os Apps Isolados da Web não funcionem com extensões de imediato, é possível
conectar extensões de sua propriedade a eles. Para isso, edite o arquivo de manifesto da extensão. A seção externally_connectable do manifesto
define com quais páginas da Web externas ou outras extensões do Chrome sua extensão pode
interagir. Adicione a origem da sua IWA no campo matches em
externally_connectable. Não se esqueça de incluir o esquema isolated-app://:
{
"externally_connectable": {
"matches": ["isolated-app://79990854-bc9f-4319-a6f3-47686e54ed29/*"]
}
}
Isso permite que a extensão seja executada no app da Web isolado, mas não que ela injete conteúdo nele. Você só pode transmitir mensagens entre a extensão e o IWA.