Selecionar idioma

Dominando a Arte da Segurança em Progressive Web Apps

Progressive Web Apps (PWAs) tornaram‑se o padrão de‑facto para oferecer experiências semelhantes a aplicativos na web aberta. Suas principais vantagens—capacidade offline, notificações push e instalabilidade—também introduzem novas superfícies de ataque que sites tradicionais raramente enfrentam. Este artigo aprofunda o ciclo de vida da segurança de uma PWA, combinando endurecimento em nível de rede, proteções em tempo de execução e boas práticas operacionais. Ao final, você terá um checklist aplicável a qualquer projeto, seja um simples leitor de notícias ou uma plataforma de comércio eletrônico complexa.

TL;DR: Proteja sua PWA com HTTPS, imponha CSP rigorosa, sandbox os service workers, valide todas as entradas e adote uma rotina contínua de monitoramento.


1. Camada de Transporte – A Primeira Linha de Defesa

1.1 Imponha HTTPS em Todo Lugar

Todos os navegadores modernos exigem HTTPS para o registro de service workers. Entretanto, alguns recursos (ex.: análises de terceiros) ainda podem ser carregados via HTTP, gerando alertas de conteúdo misto e abrindo brechas para ataques man‑in‑the‑middle (MITM).

Passos essenciais:

  1. Obtenha um certificado TLS confiável (Let’s Encrypt, Cloudflare, etc.).
  2. Redirecione todas as requisições http:// para https:// via configuração do servidor.
  3. Habilite HSTS (HTTP Strict Transport Security) para forçar os navegadores a usar HTTPS por um período predefinido.
# Exemplo de trecho NGINX
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    # Configurações TLS ...
}

Nota: O HSTS elimina ataques de downgrade, mas requer planejamento cuidadoso porque, uma vez definido, os navegadores recusarão conexões HTTP durante o período especificado.

1.2 Pinagem de Certificado (Opcional)

Para PWAs altamente sensíveis—bancários, registros de saúde—considere pinagem de certificado via Public Key Pinning Extension for HTTP (HPKP). Embora o HPKP esteja sendo descontinuado devido a riscos de implantação, você pode alcançar segurança semelhante com cabeçalhos Expect‑CT, que impõem Transparency de Certificados.

Expect-CT: max-age=86400, enforce, report-uri="https://example.com/report"

2. Endurecimento do Service Worker

Service workers são o coração da capacidade offline de uma PWA. Eles rodam em uma thread de fundo com privilégios elevados, o que os torna alvos privilegiados de exploração.

2.1 Limitação de Escopo

Defina o scope mais restrito possível ao registrar um service worker. Isso impede que o worker intercepte requisições fora da área desejada.

navigator.serviceWorker.register('/sw.js', { scope: '/app/' })
  .then(reg => console.log('SW registrado com escopo:', reg.scope));

2.2 Verifique a Integridade com Subresource Integrity (SRI)

Se carregar o script do service worker de um CDN, proteja‑o com SRI para garantir que o código obtido corresponde ao hash esperado.

<script src="https://cdn.example.com/sw.js"
        integrity="sha384-abc123..."
        crossorigin="anonymous"></script>

2.3 Política de Segurança de Conteúdo para Service Workers

Uma CSP rigorosa pode impedir que o worker carregue scripts maliciosos ou se conecte a origens não desejadas.

Content-Security-Policy: script-src 'self' https://trusted.cdn.com; 
                         connect-src 'self' https://api.example.com;

Dica: Use a diretiva worker-src (suportada nos navegadores mais recentes) para listar explicitamente as origens permitidas para scripts de workers.

2.4 Gerenciamento de Estado e Validação de Cache

Nunca confie cegamente nas entradas de cache. Sempre valide a frescura das respostas armazenadas, especialmente para tokens de autenticação ou dados pessoais.

self.addEventListener('fetch', event => {
  const url = new URL(event.request.url);
  if (url.pathname.startsWith('/api/')) {
    // Ignora o cache para dados dinâmicos
    event.respondWith(fetch(event.request));
    return;
  }
  // Estratégia padrão cache‑first para recursos estáticos
  event.respondWith(
    caches.match(event.request).then(cached => cached || fetch(event.request))
  );
});

3. Proteções em Tempo de Execução – CSP, Permissões e Sandbox

3.1 CSP Completa

Uma CSP bem‑elaborada reduz o risco de Cross‑Site Scripting (XSS) e Injeção de Dados. Abaixo, um exemplo de política adaptada a uma PWA típica:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'sha256-XYZ' https://analytics.example.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.example.com wss://socket.example.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';
  • script-src inclui um hash para scripts inline, evitando unsafe-inline.
  • frame-ancestors 'none' desativa clickjacking.
  • connect-src lista as APIs e endpoints WebSocket permitidos.

3.2 Permissions Policy (antiga Feature‑Policy)

Restrinja recursos poderosos do navegador que a PWA possa herdar inadvertidamente.

Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=()

3.3 Atributo Sandbox para Conteúdos Incorporados

Se sua PWA incorpora iframes de terceiros, sandbox‑e‑os para impedir a execução de scripts e navegação indevida.

<iframe src="https://maps.example.com"
        sandbox="allow-scripts allow-same-origin"
        loading="lazy"></iframe>

4. Autenticação & Autorização

4.1 Auth baseada em Token com JWT

Utilize JSON Web Tokens (JWT) para autenticação sem estado, mas nunca os armazene em localStorage—use cookies Secure, HttpOnly para mitigar roubos por XSS.

Set-Cookie: token=eyJhbGciOi...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600

4.2 Rotação de Refresh Tokens

Implemente refresh tokens rotativos para limitar o impacto de um token comprometido.

  1. O cliente envia o refresh token.
  2. O servidor o valida e emite um novo access token e um novo refresh token.
  3. O refresh token antigo é invalidado no banco de dados.

4.3 Mitigação de CSRF

Mesmo com cookies SameSite, use tokens anti‑CSRF para requisições POST que alterem estado.

<input type="hidden" name="csrf_token" value="{{ .CSRFToken }}">

No servidor, verifique se o token corresponde à sessão.


5. Armazenamento Seguro de Dados

PWAs podem armazenar dados via IndexedDB, Cache API e Web Storage. Cada um tem considerações de segurança próprias.

ArmazenamentoAdequaçãoDicas de Segurança
Cache APIRecursos estáticos, fallback offlineCache apenas recursos imutáveis. Use nomes de cache versionados para remover dados obsoletos.
IndexedDBDados estruturados, preferências do usuárioCriptografe campos sensíveis no cliente usando a Web Crypto API.
LocalStorage / SessionStorageDados pequenos e não sensíveisEvite guardar segredos. Qualquer script na página pode ler esses dados.

5.1 Exemplo: Criptografando Dados no IndexedDB

async function encryptAndStore(key, value) {
  const cryptoKey = await crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  );
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const encoded = new TextEncoder().encode(value);
  const ciphertext = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv },
    cryptoKey,
    encoded
  );
  const db = await openDB('secure-store', 1, {
    upgrade(db) { db.createObjectStore('secrets'); }
  });
  await db.put('secrets', { iv, ciphertext }, key);
}

6. Monitoramento, Auditoria e Resposta a Incidentes

Segurança não é uma configuração única; é um ciclo contínuo.

6.1 Varredura Automatizada

  • Use OWASP ZAP ou Burp Suite para escanear XSS, CSRF e cabeçalhos inseguros.
  • Integre auditorias Lighthouse ao pipeline CI/CD para garantir conformidade PWA.

6.2 Logging em Tempo de Execução

Capture erros do service worker e encaminhe‑os a um endpoint seguro para análise.

self.addEventListener('error', event => {
  fetch('https://logs.example.com/collect', {
    method: 'POST',
    body: JSON.stringify({ message: event.message, stack: event.error.stack })
  });
});

6.3 Playbook de Incidentes

  1. Detectar: Alerta disparado por tráfego anômalo ou relatórios de violação CSP.
  2. Conter: Revogar JWTs comprometidos, rotacionar chaves de API.
  3. Erradicar: Corrigir código vulnerável, atualizar cache do service worker.
  4. Recuperar: Implantar nova versão, monitorar recorrência.
  5. Post‑mortem: Documentar causa raiz, atualizar checklist de segurança.

7. Visão Geral Visual – Camadas de Segurança em uma PWA

  flowchart TB
    subgraph "Camada de Transporte"
        H["HTTPS"]
        S["HSTS"]
    end
    subgraph "Service Worker"
        SW["Limitação de Escopo"]
        CS["Validação de Cache"]
    end
    subgraph "Tempo de Execução"
        CSP["Content Security Policy"]
        PP["Permissions Policy"]
        SAN["iFrames em Sandbox"]
    end
    subgraph "Autenticação e Dados"
        JWT["Cookies Seguros"]
        REF["Rotação de Refresh"]
        ENC["Criptografia no IndexedDB"]
    end
    subgraph "Monitoramento"
        SCAN["OWASP ZAP"]
        LOG["Logging em Tempo Real"]
    end

    H --> SW --> CSP --> JWT --> SCAN
    S --> SW
    CS --> PP
    PP --> ENC
    LOG --> SCAN

O diagrama ilustra como cada controle de segurança se apoia no anterior, formando uma arquitetura de defesa em profundidade.


8. Checklist – Referência Rápida para uma PWA Segura

  • Servir todo o conteúdo via HTTPS com HSTS habilitado.
  • Registrar service workers com o escopo mais restrito possível.
  • Aplicar Subresource Integrity para scripts carregados remotamente.
  • Impor CSP rigorosa, incluindo worker-src e hashes de script.
  • Usar Permissions‑Policy para desativar recursos de navegador não utilizados.
  • Armazenar tokens de autenticação em cookies Secure e HttpOnly; jamais em localStorage.
  • Rotacionar refresh tokens e validar tokens anti‑CSRF em requisições que alterem estado.
  • Criptografar dados sensíveis no IndexedDB.
  • Executar varreduras OWASP ZAP automatizadas em cada Pull Request.
  • Configurar logging em tempo real de erros do service worker.
  • Manter um playbook de resposta a incidentes atualizado.

9. Perguntas Frequentes

P1: PWAs precisam de Service Worker para segurança?
Não. Medidas como HTTPS, CSP e cookies seguros funcionam independentemente. Contudo, o Service Worker é onde a maioria dos ataques em tempo de execução ocorre, exigindo endurecimento adicional.

P2: Posso usar unsafe-inline em CSP para estilos?
Evite ao máximo. Prefira gerar hashes ou nonces para estilos inline, ou mova‑os para arquivos CSS externos.

P3: Com que frequência devo renovar certificados TLS?
Let’s Encrypt emite certificados de 90 dias; automatize a renovação. Para certificados auto‑assinados ou comerciais, limite a validade a, no máximo, 1 ano.


10. Conclusão

Progressive Web Apps desfocam a linha entre experiências nativas e web, oferecendo recursos poderosos que simultaneamente ampliam a superfície de ataque. Ao combinar segurança no transporte, restringir o escopo dos service workers, impor uma Política de Segurança de Conteúdo rigorosa e adotar práticas robustas de autenticação, você pode proteger sua PWA sem sacrificar desempenho.

Lembre‑se: segurança é uma jornada, não um destino. Mantenha dependências atualizadas, audite seu código regularmente e fique atento a ameaças emergentes. Com as práticas descritas aqui, sua PWA estará bem armada contra os ataques web mais comuns.


Veja Também

topo
© Scoutize Pty Ltd 2025. All Rights Reserved.