Socket.dev / supply-chain finding attestation (Português (Brasil))
§1 — Instalação da CA raiz para MITM (77484.js)
Seção intitulada “§1 — Instalação da CA raiz para MITM (77484.js)”Arquivos-fonte:
src/mitm/cert/install.ts— funções públicasinstallCert()/uninstallCert()einstallCertWindows/Mac/Linuxespecíficas para cada plataforma.src/mitm/systemCommands.ts— auxiliares compartilhados deexecFile/spawn/ PowerShell usados pelos caminhos de instalação.
Acionamento: o usuário clica em “Ativar proxy MITM” no painel local em
/dashboard/cli-tools/mitm. A rota é restrita à interface de loopback — consulte
a regra rígida nº 17 em CLAUDE.md e
src/server/authz/routeGuard.ts::isLocalOnlyPath(). Um JWT vazado e exposto por
meio de um túnel não pode acionar esse caminho de código.
Operações privilegiadas executadas (por plataforma):
| SO | Comando(s) |
|---|---|
| Windows | certutil -addstore Root <cert> via UAC |
| macOS | sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <cert> |
| Linux | sudo cp <cert> <distro-trust-dir> + sudo update-ca-certificates (Debian) / sudo update-ca-trust (RHEL/SUSE) |
| Linux+Firefox/Chromium | atualização do banco de dados NSS de cada perfil via certutil -d sql:<profile> |
Esses são os mesmos comandos usados por mitmproxy, Charles Proxy, Fiddler e
Caddy. O fato de eles existirem no OmniRoute está documentado em
docs/security/STEALTH_GUIDE.md.
Mitigação da v3.8.6:
runElevatedPowerShell()não usa mais-EncodedCommand <base64utf16le>. O payload elevado é gravado em um arquivo temporário.ps1para cada chamada (modo 0o600, dentro de um diretório privadomkdtempSync) e referenciado por meio de-File. O arquivo é desvinculado emfinally. Isso remove a assinatura clássica de elevação via PowerShell usando base64, sinalizada pelo classificador de IA do Socket.dev.installCertWindowscontém um bloco inlineSECURITY-AUDITOR-NOTE:que aponta para este documento.
Por que o mantemos: o proxy MITM é um recurso documentado usado por
docs/security/STEALTH_GUIDE.md e docs/frameworks/MITM-PROXY.md. Removê-lo
interromperia o conjunto de recursos da ponte de agentes.
§2 — Importação de credenciais do Zed (app/api/providers/zed/import/route.js)
Seção intitulada “§2 — Importação de credenciais do Zed (app/api/providers/zed/import/route.js)”Arquivos-fonte:
src/app/api/providers/zed/discover/route.ts(novo na v3.8.6)src/app/api/providers/zed/import/route.tssrc/lib/zed-oauth/keychain-reader.tssrc/lib/zed-oauth/credentialFingerprint.ts(novo na v3.8.6)
Acionamento: o usuário clica em “Importar do Zed” na página local de Provedores do painel. O endpoint é protegido por requireManagementAuth. O próprio editor Zed grava suas chaves de API dos provedores no chaveiro do sistema operacional, usando nomes de serviço documentados — consulte https://zed.dev/docs/ai/llm-providers.
Comportamento da v3.8.5 (o que o Socket.dev sinalizou):
POST /import descobria as credenciais e as salvava automaticamente no armazenamento SQLite local em uma única operação. Sem confirmação por conta, sem impressão digital, apenas “N tokens encontrados, todos importados”.
Mitigação da v3.8.6 — confirmação em 2 etapas:
POST /api/providers/zed/discoverretorna{ candidates: [{ provider, service, account, fingerprint }] }. O token bruto nunca é transmitido. A impressão digital ésha256(service|account|token).slice(0,16).- O painel exibe a lista de candidatos, o operador seleciona quais deseja
importar e envia
{ confirmedAccounts: [{ service, account, fingerprint }] }paraPOST /api/providers/zed/import. - O endpoint de importação relê o chaveiro no servidor e filtra por
(service, account, fingerprint). Uma resposta de descoberta adulterada ou reproduzida não consegue induzir o endpoint de importação a salvar um token não relacionado — se o token ativo tiver sido alterado desde a descoberta, a impressão digital não corresponderá mais e a credencial será ignorada.
Uma variável de ambiente OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true preserva o
comportamento da v3.8.5 para operadores que ainda não atualizaram suas
automações. Ela será removida na v3.9.
Por que mantemos isso: a importação do Zed é o caminho de integração mais amigável para usuários que já utilizam o Zed e desejam espelhar suas chaves de provedores no OmniRoute sem precisar colá-las novamente.
§3 — execFile / spawn / PowerShell elevado (21843.js)
Seção intitulada “§3 — execFile / spawn / PowerShell elevado (21843.js)”Arquivos-fonte: src/mitm/systemCommands.ts.
Por que foi sinalizado: o chunk reexporta execFileWithPassword,
runElevatedPowerShell e o auxiliar compartilhado quotePowerShell. O
classificador de IA do Socket.dev os interpreta como um “kit de ferramentas
genérico para execução no host + elevação de privilégios”. No OmniRoute, eles
são usados somente pelo fluxo de instalação do certificado MITM (§1) e por
execFileWithPassword para a execução de comandos sudo.
Mitigação da v3.8.6:
- Refatoração de
runElevatedPowerShell(consulte §1). - Um bloco
SECURITY-AUDITOR-NOTE:embutido tanto emrunElevatedPowerShellquanto emexecFileWithPassworddocumenta os chamadores permitidos e a lista fixa de executáveis. - A chamada
spawn()deexecFileWithPasswordcontém um marcadornosemgrepcom a lista permitida de executáveis que o auxiliar pode receber — não existe nenhum caminho da entrada do usuário atéfinalCommand/finalArgs.
§4 / §6 — Supervisor do serviço 9router (api/services/9router/{start,restart}/route.js)
Seção intitulada “§4 / §6 — Supervisor do serviço 9router (api/services/9router/{start,restart}/route.js)”Arquivos-fonte:
src/app/api/services/9router/_lib.ts— fábrica do supervisor.src/app/api/services/9router/{start,stop,restart,status,install,update,auto-start}/route.ts.src/lib/services/ServiceSupervisor.ts— spawn genérico / sondagem de integridade / buffer de logs.
Acionamento: o usuário clica em “Instalar” / “Iniciar” na página de serviços integrados do painel local.
Proteções já existentes:
- Todas as rotas
/api/services/*são LOCAL_ONLY conformesrc/server/authz/routeGuard.ts(regra rígida nº 17). A restrição a loopback ocorre antes de qualquer verificação de autenticação — um JWT vazado não consegue acessá-las. - O registro do 9router no banco de dados é criado com
status='not_installed', auto_start=0(consultesrc/lib/db/migrations/071_services.sql:19). O serviço não é iniciado na primeira execução. spawn()é chamado com o caminho do binário retornado porresolveSpawnArgs(apiKey, PORT)emsrc/lib/services/installers/ninerouter.ts, que consiste em uma lista fixa de binários compatíveis.- Stdout/stderr é armazenado em buffer na memória (limite de 5 MB, consulte
_lib.ts) — nada é gravado em disco, a menos que o usuário habilite o registro de logs no painel.
Mitigação da v3.8.6: nenhuma alteração funcional. O perfil de compilação
mínimo (OMNIROUTE_BUILD_PROFILE=minimal) substitui
src/lib/services/installers/ninerouter.ts por um stub para usuários que
desejam que os caminhos privilegiados sejam fisicamente removidos do pacote.
Por que mantemos isso: o 9router é um serviço complementar opcional e instalável localmente (pense em algo como um plugin do WordPress) — adesão estritamente voluntária.
§5 — Gravação de credenciais do OmniRoute Cloud Sync (api/keys/[id]/route.js)
Seção intitulada “§5 — Gravação de credenciais do OmniRoute Cloud Sync (api/keys/[id]/route.js)”Arquivos-fonte:
src/lib/cloudSync.ts—syncToCloud()/updateLocalTokens().src/app/api/keys/[id]/route.ts— invocasyncKeysToCloudIfEnabled().
Gatilho: isCloudEnabled() retorna true (definido pelo painel) e
CLOUD_URL está configurada. Com ambos desativados, nenhuma chamada de rede
de saída é feita ao endpoint do Cloud.
Comportamento da v3.8.5 (o bug que o Socket.dev detectou corretamente):
updateLocalTokens() sobrescrevia accessToken, refreshToken e
providerSpecificData com os dados da resposta do Cloud quando
cloudUpdatedAt > localUpdatedAt. Sem HMAC, sem assinatura, sem checksum. Uma
CLOUD_URL configurada incorretamente ou hostil (ou um MITM no canal) poderia
substituir silenciosamente os tokens OAuth do provedor.
Mitigação na v3.8.6:
- Verificação de HMAC:
verifyCloudSignature(rawBody, sigHeader)verifica o cabeçalhoX-Cloud-Sig(HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody)) antes de analisar o JSON. Se o segredo estiver definido, a assinatura será obrigatória. Caso contrário (modo legado), um aviso será registrado e a resposta será aceita — o segredo será obrigatório na v3.9. - Ativação explícita de campos secretos:
accessToken/refreshToken/providerSpecificDatasão sobrescritos somente quandoOMNIROUTE_CLOUD_SYNC_SECRETS=true. O modo padrão sincroniza apenas metadados que não são credenciais (expiresAt,status,lastError*,rateLimitedUntil,updatedAt). Essa é uma alteração incompatível para usuários que dependiam da sincronização remota de tokens — eles devem ativá-la explicitamente.
Por que mantemos esse recurso: o Cloud Sync é a única forma de um tenant do OmniRoute Cloud centralizar as credenciais da equipe. A correção torna o modelo de ameaças transparente: “o servidor assina, o cliente verifica, o operador ativa explicitamente.”
Perfil de build: minimal
Seção intitulada “Perfil de build: minimal”Para usuários que precisam de um artefato compatível com o Socket, faça o build com:
OMNIROUTE_BUILD_PROFILE=minimal npm run buildO NormalModuleReplacementPlugin do webpack cria aliases de quatro módulos para stubs:
| Módulo | Stub |
|---|---|
src/mitm/cert/install.ts |
src/mitm/cert/install.stub.ts |
src/lib/zed-oauth/keychain-reader.ts |
src/lib/zed-oauth/keychain-reader.stub.ts |
src/lib/cloudSync.ts |
src/lib/cloudSync.stub.ts |
src/lib/services/installers/ninerouter.ts |
src/lib/services/installers/ninerouter.stub.ts |
Cada stub exporta a mesma interface, mas todas as funções lançam um
featureDisabledError(name) em tempo de execução. As rotas que dependem do
módulo desativado retornam HTTP 503 com uma mensagem clara, em vez de ativar
o caminho de código sensível.
O bundle resultante destina-se à publicação como omniroute-secure. Consulte
docs/ops/PUBLISHING_SECURE.md para obter as instruções de publicação.
Divisão do plugin (acompanhada para a v4)
Seção intitulada “Divisão do plugin (acompanhada para a v4)”A longo prazo, pretendemos dividir o pacote npm em módulos que possam ser auditados separadamente. Consulte o marco da v4 no rastreador de issues do GitHub para acompanhar a issue correspondente.
HagiCode
HagiCode é um ambiente de programação com agentes, fluxos estruturados, execução multiagente e visualizações Hero Dungeon.
Transforme ideias em software útil com um fluxo de trabalho com agentes mais inteligente, rápido e agradável.

- SmartFluxos estruturados transformam intenções em um caminho executável da ideia à entrega.
- EfficientFluxos multiagente mantêm pesquisa, implementação e revisão em andamento simultaneamente.
- FunO Hero Dungeon torna longas sessões de programação mais visuais e colaborativas.