Files
cybercore-signer/docs/browser-compatibility.md

6.4 KiB

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

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<br/>Origin: https://meusistema.com.br<br/>Access-Control-Request-Private-Network: true
    Agent-->>Browser: HTTP 204 No Content<br/>Access-Control-Allow-Origin: *<br/>Access-Control-Allow-Private-Network: true<br/>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:

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/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:
    import { CyberCoreSigner } from '@cybercore/signer-sdk';
    
    const signer = new CyberCoreSigner();
    
    if (!(await signer.isInstalled())) {
      mostrarModalInstalacaoAgente();
    }
    
  3. Capture AgentNotRunningError e exiba o guia de ajuda:
    import { AgentNotRunningError } from '@cybercore/signer-sdk';
    
    try {
      await signer.connect();
    } catch (err) {
      if (err instanceof AgentNotRunningError) {
        console.info(err.actionableGuidance);
        exibirAjudaAoUsuario(err.actionableGuidance);
      }
    }