Seu endereço está na allowlist — isso faz do remetente você?

Você conecta uma caixa de entrada ao Hermes com uma allowlist que contém exatamente um endereço — o seu — e considera a porta fechada. Então, um dia, o bot responde a uma mensagem de um domínio que você nunca viu, assinada com o seu nome. A allowlist não estava mal configurada. O problema é que a string que você colocou nela e o “remetente” daquela mensagem nunca foram o mesmo tipo de coisa.
Dois patches de segurança mesclados em 2026-09-27 corrigem esse mesmo erro em dois lugares: o gateway de e-mail e o gateway SimpleX incluído autorizavam remetentes usando um campo que o próprio remetente escreve sobre si mesmo. Ambos são P1 e ambos estão em main hoje.
Um nome de exibição é texto livre: como a allowlist do SimpleX foi burlada
O SimpleX foi feito para privacidade: não há IDs de usuário persistentes. Cada contato recebe um ID interno opaco (contactId) gerado no momento da conexão — essa é a identidade. O nome de exibição é o que a outra parte digitou no próprio cliente.
Antes da correção, a regra de autorização do gateway era “permitir se o contactId ou o nome de exibição do remetente corresponder à allowlist”. Nomes de exibição colidem e podem ser alterados a qualquer momento, então qualquer contato podia definir o próprio nome com um valor que já estava na sua allowlist e começar a comandar seu bot. A brecha foi reportada em 2026-06-12 (#44729) e fechada pelo PR #125034 em 27 de setembro.
O que acontece agora:
SIMPLEX_ALLOWED_USERScorresponde apenas acontactIds numéricos; nomes de exibição são ignorados.- Ao conectar, o adaptador registra um aviso listando as entradas da allowlist que não parecem IDs de contato, porque essas entradas não fazem mais nada. Muito provavelmente você precisará substituí-las.
- A documentação, o
plugin.yamle o prompt dehermes gateway setupagora pedem todos IDs de contato.
Para encontrar o seu: inicie o daemon simplex-chat, abra a conversa com seu contato do agente e leia o ID numérico nos logs de sessão — ou rode /contacts no daemon.
E-mail é mais sutil: o segundo endereço dentro do From
O e-mail é pior porque a RFC 5322 permite que From seja “nome de exibição mais endereço”, e o nome de exibição pode conter quase qualquer coisa. O parser antigo pegava o primeiro endereço entre chaves angulares que encontrava:
From: "Victim <[email protected]>" <[email protected]>
O remetente real aqui é [email protected], mas o código antigo resolvia [email protected] — o endereço que está na sua allowlist.
O mesmo patch fecha mais duas formas:
| Forma do ataque | Antes | Depois |
|---|---|---|
Um segundo endereço em From (listas de discussão, grupos, um endereço dentro da parte de exibição) |
Uma identidade “legítima” era resolvida e autorizada | O From resolve vazio e a mensagem é descartada antes da autenticação ou do despacho |
Um From enorme ou profundamente aninhado (mais de 2048 caracteres, ou mais de 64 parênteses de comentário) |
O parsing em Python puro levava segundos com entrada hostil, segurando o GIL | Os limites de tamanho e de aninhamento o descartam de imediato — um valor de 200 KB em cerca de 2 ms |
Texto controlado pelo remetente dentro do cabeçalho Authentication-Results do servidor receptor (partes locais entre aspas, comentários) |
Um veredito forjado dmarc=pass / spf=pass podia ser lido |
As cláusulas são separadas respeitando strings entre aspas e comentários aninhados; uma aspa ou parêntese desbalanceado falha de forma fechada, e cada veredito é lido apenas do seu próprio method=result |
Mais um critério mudou: dmarc=pass não é mais aceito por si só. Ele só conta quando o header.from do veredito está alinhado com o domínio do From que foi analisado (iguais, ou um é sufixo com ponto do outro) — caso contrário, basta ao atacante ter um domínio que controle para passar no DMARC e então avalizar qualquer From. Esta é a correção GHSA-rxqh-5572-8m77.
O que sua instalação faz agora
No lado do e-mail, “o remetente precisa estar autenticado” vem ativado por padrão:
# ~/.hermes/config.yaml
platforms:
email:
require_authenticated_sender: true # padrão: true
authserv_id: "your-mx.example.com" # opcional: fixa Authentication-Results no seu próprio servidor
A variável de ambiente é EMAIL_AUTHSERV_ID. Se o seu servidor de correio não carimba esse cabeçalho de forma alguma, a saída de emergência documentada é require_authenticated_sender: false (ou EMAIL_TRUST_FROM_HEADER=true) — isso restaura o comportamento antigo, e a documentação diz claramente que significa aceitar o risco. A configuração completa da plataforma de e-mail (variáveis IMAP/SMTP, códigos de pareamento, EMAIL_ALLOWED_USERS) está na documentação de e-mail.
Para as operações diárias do gateway, veja nossa referência do comando hermes gateway. Se você quer a ideia espelhada — autenticidade de saída em vez de entrada —, o post sobre webhooks mostra como o Hermes assina os próprios eventos com HMAC para que os receptores possam verificar a origem.
Uma coisa que não ficou mais rígida: a saída. hermes send --to simplex:alice "hello" continua funcionando por nome de exibição, porque ali é você quem escolhe o destino. O que ficou mais rígido é apenas quem pode dar ordens ao seu agente.
Status de lançamento
Os dois patches foram mesclados em 2026-09-27, depois da tag de release v0.21.5 (v2026.9.24), então por enquanto eles vivem apenas em main: hermes update os traz, ou aguarde a próxima tag.
A conclusão
Uma string em uma allowlist nunca foi uma identidade — é uma linha que outra pessoa escreveu para você ler. Essas correções reancoram o “quem está falando comigo” em algo que o remetente não pode decidir: o contactId gerado no momento da conexão, no SimpleX, e um veredito carimbado pelo seu próprio servidor receptor, no e-mail, além de uma checagem de que o veredito realmente cobre o domínio do From. Se você mesmo roda um bot, vale adotar dois hábitos: substituir entradas da allowlist por IDs de contato reais e fazer seu servidor de correio carimbar cabeçalhos de autenticação em vez de desligar essa confiança.