---
title: "Dominando a Arte da Segurança em Progressive Web Apps"
---

# 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.

```nginx
# 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.

```http
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.

```javascript
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.

```html
<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.

```http
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.

```javascript
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:

```http
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.

```http
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.

```html
<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.

```http
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.

```html
<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.

| Armazenamento | Adequação | Dicas de Segurança |
|---------------|-----------|----------------------|
| **Cache API** | Recursos estáticos, fallback offline | Cache apenas recursos imutáveis. Use nomes de cache versionados para remover dados obsoletos. |
| **IndexedDB** | Dados estruturados, preferências do usuário | Criptografe campos sensíveis no cliente usando a Web Crypto API. |
| **LocalStorage / SessionStorage** | Dados pequenos e não sensíveis | Evite guardar segredos. Qualquer script na página pode ler esses dados. |

### 5.1 Exemplo: Criptografando Dados no IndexedDB

```javascript
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.

```javascript
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

```mermaid
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.

---

## <span class='highlight-content'>Veja</span> Também

- [MDN Web Docs – Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)
- [OWASP Top Ten Project](https://owasp.org/www-project-top-ten/)
- [Mozilla – Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
- [Web.dev – HTTPS and HSTS](https://web.dev/transport-layer-security/)
- [RFC 6797 – HTTP Strict Transport Security (HSTS)](https://tools.ietf.org/html/rfc6797)