From 50b5feced51492eec829623e311f08ccb569a2f1 Mon Sep 17 00:00:00 2001 From: Claudecio Martins Date: Tue, 20 Oct 2026 16:42:40 -0300 Subject: [PATCH] docs(browser): document https to localhost compatibility and private network access --- docs/browser-compatibility.md | 129 ++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs/browser-compatibility.md diff --git a/docs/browser-compatibility.md b/docs/browser-compatibility.md new file mode 100644 index 0000000..5336e6d --- /dev/null +++ b/docs/browser-compatibility.md @@ -0,0 +1,129 @@ +# Compatibilidade de Navegadores e Acesso de Rede Privada (CCSP/1) + +Este documento detalha o funcionamento, as garantias de segurança e os requisitos de compatibilidade entre aplicações web (servidas sob **HTTPS**) e o agente desktop **CyberCore Signer** em loopback local (`http://127.0.0.1:21325`). + +--- + +## 1. Contexto Arquitetural: HTTPS para Loopback HTTP + +Tradicionalmente, navegadores modernos impedem o carregamento de recursos inseguros (`http://`) a partir de contextos seguros (`https://`), mecanismo conhecido como **Mixed Content**. + +No entanto, para agentes de assinatura digital locais e periféricos de hardware, o consórcio **W3C (Secure Contexts Specification)** e os motores de renderização modernos tratam o loopback IPv4 (`127.0.0.1`) e `localhost` como **Origens Potencialmente Confiáveis (*Potentially Trustworthy Origins*)**. + +```mermaid +sequenceDiagram + autonumber + participant Web as Aplicação Web (HTTPS) + participant Browser as Navegador (Chrome/Firefox/Safari) + participant Agent as CyberCore Signer (127.0.0.1:21325) + + Note over Web,Agent: 1. Preflight CORS + Private Network Access (PNA) + Web->>Browser: fetch("http://127.0.0.1:21325/ccsp/v1/sign", { method: "POST" }) + Browser->>Agent: OPTIONS /ccsp/v1/sign
Origin: https://meusistema.com.br
Access-Control-Request-Private-Network: true + Agent-->>Browser: HTTP 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Private-Network: true
Access-Control-Allow-Methods: GET, POST, OPTIONS + Note over Browser,Agent: 2. Requisição Real CCSP/1 + Browser->>Agent: POST /ccsp/v1/sign (JSON Digest) + Agent-->>Browser: HTTP 200 OK (Assinatura Base64) + Browser-->>Web: Retorno Promise Resolvida +``` + +--- + +## 2. Private Network Access (PNA / W3C) + +O **Private Network Access (PNA)** é uma especificação de segurança do W3C (adotada inicialmente pelo motor Chromium a partir do Chrome 98+) com o objetivo de proteger a rede local contra ataques de Cross-Site Request Forgery (CSRF). + +### Como a especificação classifica as redes: +1. **Pública (*public*):** A internet pública (ex: `https://meusistema.com.br`). +2. **Privada (*private*):** Redes locais RFC 1918 (ex: `192.168.x.x`, `10.x.x.x`). +3. **Local (*local*):** A máquina do próprio usuário (`127.0.0.1`, `localhost`). + +Quando uma página em um espaço de IP mais público solicita um recurso em um espaço mais restrito (como `public` $\rightarrow$ `local`), o navegador dispara uma requisição preliminar **Preflight PNA**. + +### Headers Enviados pelo Navegador: +```http +OPTIONS /ccsp/v1/sign HTTP/1.1 +Host: 127.0.0.1:21325 +Origin: https://meusistema.com.br +Access-Control-Request-Method: POST +Access-Control-Request-Headers: Content-Type, X-CyberCore-AppId +Access-Control-Request-Private-Network: true +``` + +### Resposta Padrão do CyberCore Signer (`CcspServer`): +O servidor do agente desktop intercepta requisições `OPTIONS` e responde imediatamente com: +```http +HTTP/1.1 204 No Content +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET, POST, OPTIONS +Access-Control-Allow-Headers: Content-Type, Authorization, X-CyberCore-AppId, Origin, Accept +Access-Control-Allow-Private-Network: true +Access-Control-Max-Age: 86400 +Connection: close +``` + +> [!NOTE] +> O cabeçalho `Access-Control-Allow-Private-Network: true` é fundamental para autorizar o navegador a enviar requisições privadas originadas de sites HTTPS públicos. + +--- + +## 3. Matriz de Compatibilidade de Navegadores + +| Navegador | Versão Mínima | Suporte HTTPS $\rightarrow$ 127.0.0.1 | Comportamento PNA | Requer Ação do Usuário? | +| :--- | :---: | :---: | :---: | :---: | +| **Google Chrome** | 88+ | ✅ Suportado | PNA ativo com preflight | Não (automático) | +| **Microsoft Edge** | 88+ | ✅ Suportado | PNA ativo com preflight | Não (automático) | +| **Mozilla Firefox** | 84+ | ✅ Suportado | Trata 127.0.0.1 como Secure Context | Não (automático) | +| **Opera / Brave** | Recentes | ✅ Suportado | Idêntico ao Chromium (ver nota Brave) | Pode exigir ajuste no Shields | +| **Apple Safari** | 15.4+ (macOS) | ✅ Suportado | Trata loopback como seguro | Não | + +--- + +## 4. Casos de Borda e Soluções (Troubleshooting) + +### 4.1. Navegador Brave (Brave Shields) +O Brave possui um mecanismo agressivo de proteção que pode bloquear preflights para `127.0.0.1`. +- **Sintoma:** O SDK lança `AgentNotRunningError`, mesmo com o agente em execução. +- **Resolução:** O usuário deve clicar no ícone do escudo (Shields) na barra de endereços da aplicação e desativar temporariamente o bloqueio para a origem ou permitir conexões locais nas configurações (`brave://settings/shields`). + +### 4.2. Extensões de Privacidade e AdBlockers +Extensões como *uBlock Origin*, *Privacy Badger* ou *NoScript* podem conter regras genéricas de bloqueio para portas locais. +- **Resolução:** Adicionar a URL da sua aplicação web à lista de permissões (*allowlist*) da extensão. + +### 4.3. Softwares de Antivírus e Endpoint Protection +Alguns antivírus com módulo de "Proteção Web" ou "Inspeção HTTPS" tentam atuar como proxy transparente no loopback local: +- **Resolução:** Configurar o antivírus para excluir a porta `21325` da inspeção de tráfego local. + +### 4.4. Políticas Corporativas de Grupo (GPO / Chromium Enterprise) +Em ambientes corporativos restritos, administradores de rede podem bloquear chamadas a redes privadas via política: +- Política Chromium: `InsecurePrivateNetworkRequestsAllowed` ou `InsecurePrivateNetworkRequestsAllowedForUrls`. +- **Resolução:** Adicionar a URL do portal web corporativo na política `InsecurePrivateNetworkRequestsAllowedForUrls`. + +--- + +## 5. Boas Práticas para Desenvolvedores Web + +1. **Use sempre o SDK `@cybercore/signer-sdk`:** Ele gerencia timeouts, fallbacks de preflight e detecção de conectividade. +2. **Utilize `isInstalled()` antes de iniciar fluxos de assinatura:** + ```javascript + import { CyberCoreSigner } from '@cybercore/signer-sdk'; + + const signer = new CyberCoreSigner(); + + if (!(await signer.isInstalled())) { + mostrarModalInstalacaoAgente(); + } + ``` +3. **Capture `AgentNotRunningError` e exiba o guia de ajuda:** + ```javascript + import { AgentNotRunningError } from '@cybercore/signer-sdk'; + + try { + await signer.connect(); + } catch (err) { + if (err instanceof AgentNotRunningError) { + console.info(err.actionableGuidance); + exibirAjudaAoUsuario(err.actionableGuidance); + } + } + ```