### Sumário Um erro invertido- booleano na integração de `boring- tls` de letra desativa silenciosamente a verificação do nome de host TLS para os chamadores usando a configuração padrão (strita). Um atacante no caminho que apresenta qualquer certificado válido em cadeia para qualquer domínio pode interceptar a submissão SMTP, incluindo credenciais PLAIN/LOGIN e conteúdo de mensagem, contra qualquer usuário de letra construído com a funcionalidade `boring- tls`. Outras infraestruturas TLS (`native- tls`, `rustls`) não são afetadas.
### Detalhes chato `SslConnectorBuilder::set_verify_hostname(bool)` / `verify_hostname(bool)` API toma uma bandeira *verify* — `verdadeiro` significa fazer valer a verificação do nome do hospedeiro, `false` significa pulá-lo. (Docs de aborramento: o 'TlsParametersBuilder' de letre expõe a bandeira oposta `accept_invalid_hostnames: bool` — `true` significa *aceitual* (verificação do skip), `false' significa verificar. letre passa diretamente a aborrecer em ambos os sites TLS-upgrade, invertendo a semântica: src/transport/smtp/client/net.rs: 202 (sync).verify_hostname(*accept_invalid_hostnames) src/transport/smtp/client/async_net.rs: 377 (async) config.set_verify_hostname(accept_invalid_hostnames); Comportamento concreto sob `boring- tls`: * accept_invalid_hostnames = false (o padrão estrito) → set_verify_hostname(false) → verificação hostname SKIPPED (errado; o chamador pediu para verificação estrita) * accept_invalid_hostnames = true (explicite opt- in to "dangerous") → set_verify_hostname( true) → verificação hostname ENFORCED (errado; o chamador optou por aceitar qualquer nome) Aviso próprio de Boring no `set_verify_hostname`: "Se a verificação hostname não for usada, *qualquer certificado válido para ** local será confiável para uso de qualquer outro. Isto introduz uma vulnerabilidade significativa aos ataques do homem no meio." `native- tls` (src/ transport/ smtp/ client/ tls.rs: 355 ) usa `danger_ accepta_ invalid_hostnames(self. accepta_ invalid_ hostnames)`, cujo nome da bandeira e semântica correspondem a letras — não afetados. `rustls ' usa um caminho de verificação separado — não afetados. O erro foi introduzido na PR # 797 ("Adicione suporte para chato TLS"), commit 985 Fa 7 e, primeiramente lançado em v 0.10.1, e persiste inalterado através de v 0.11.21 (último). Zero testes existentes cobrem `accept_ invalid_hostnames` de ponta a ponta com qualquer backend, por isso a inversão não foi detectada. Correção: negar a bandeira em ambos os sites de chamadas. Patch de duas linhas: -.verify_hostname(*accept_invalid_hostname) +.verify_hostname(!*accept_invalid_hostname) - config.set_verify_hostname(accept_invalid_hostname); + config.set_verify_hostname(!accept_invalid_hostname); Eu tenho o patch pronto localmente e posso empurrar para uma forca privada se um ramo de correção colaborativo for preferido.
Configuração do PoC (qualquer versão letra >= v 0.10.1, construído com a funcionalidade `boring- tls`, configuração padrão- estritamente: 1. Gere um certificado TLS para qualquer nome de máquina que o atacante controle, por exemplo, `atacker.exemplo`, assinado por qualquer CA na loja de confiança do cliente (por exemplo, um certificado Let's Encrypt é suficiente). 2. Levante um servidor SMTP atacante no caminho de rede entre o cliente letra e o MX pretendido. Faça com que ele apresente o certificado `atacker.exemplo` no STARTTLS ou TLS implícito. 3. Use letra com TLS de limite padrão para enviar para o nome de máquina real do MX, por exemplo `mail.exemplo.com`: use letra:: transport:: smtp::client::{Tls, TlsParameters}; use letra::{AsyncSmtpTransport, Tokio 1 Executor, Message}; let tls = TlsParameters::builder("mail.exemplo.com".to_owned().build_boring().unwrap(); let mailer = AsyncSmtpTransport:: :::relay( "mail.exemplo.com", )?.tls(Tls::Required(tls)).build(); mailer.send( message).await?; // tem sucesso contra o atacante Esperado com verificação do nome do host: o aperto de mãos falha porque o SAN do certe de folhas apresentado não corresponde ao `mail.exemplo.com`. Real em `boring- tls`: handsshake é bem sucedido. letre prossegue com a transação SMTP, enviando MAIL DE, RCPT TO, corpo de mensagem e quaisquer credenciais SMTP AUTH configuradas para o atacante. PoC inverso simétrico (prova a inversão, não apenas uma verificação faltando): configure `.dangerous_accept_invalid_hostnames(true)` e tente se conectar a um servidor cujo certificado SAN corresponde ao domínio de conexão. Com o erro, o aperto de mão * falha* porque letre passa "verdadeiro" para `verify_hostname` e rejeitou chato... na verdade, ele tem sucesso (saneia combina). Melhor demonstração inversa: conecte- se a um servidor cujo certificado SAN corresponde ao domínio de conexão com `accept_invalid_hostnames=true`, em seguida, conecte- se a um servidor SAN- mismatched com a mesma bandeira — este último é rejeitado, provando que a bandeira é invertida (o usuário optou por aceitar qualquer nome, mas letre aplica uma verificação rigorosa). Um projeto de carga reprodutor pode ser produzido a pedido.
### Impacto Quem é impactado: qualquer usuário letra que 1. habilita o recurso `boring- tls`, E 2. conta com a verificação de nomes de host por padrão (isto é, não chama `.dangerous_accept_invalid_hostnames(true)`). Esta é toda a população "Eu quero TLS" estrita no `boring- tls`. Eles obtêm o oposto do que pediram: um aperto de mão TLS que ignora o erro do nome do host. Exploitação: um atacante na rota de rede entre o cliente de letra e o servidor SMTP alvo, segurando qualquer certificado TLS válido em cadeia (por exemplo, um certificado gratuito Let's Encrypt para um domínio que o atacante possui), pode apresentar esse certificado quando o cliente de letra se conectar ao MX pretendido. chato aceita o aperto de mão, lettre prossegue, e o atacante ganha acesso à leitura/escreva a: * Envelope SMTP (MAI DE, RCPT TO) * Corpos de mensagens, anexos, cabeçalhos * Qualquer credencial SMTP AUTH (PLAIN, ACLIN, CRAM-MD) 5, etc.) * Qualquer assinatura DKIM e alinhamento DMARC depende de pode ser inspecionado e seletivamente deixado cair Confidencialidade e impacto de integridade: Alto. Impacto da disponibilidade: Nenhuma direta (o atacante pode optar por encaminhar ou soltar, mas o próprio erro não nega o serviço). O email-fwdr da Cloudflare identificou e mitigou de forma independente este processo a jusante promovendo uma verificação de SAN pós-handshake previamente métrica para um erro duro (fixo aterrissado 2026 - 05 - 12 ). Como estamos a ser mitigados a jusante, não estamos em um relógio de publicação; estamos reportando para que a correção a montante possa enviar e outras implementações de letras+boring- tls podem parar de depender de soluções de chamadas. Fico feliz em coordenar o tempo de embargo. versões afetadas: todas as versões de letras lançadas com suporte `boring- tls`, a partir do v 0.10.1 (PR # 797, commit 985 Fa 7 e) através de v 0.11.21 (último). Nenhum aviso ou correção prévia. Correção sugerida: negação de duas linhas da bandeira nos sites de chamadas chatas (ver Detalhes). O patch está pronto localmente e pode ser ligado a um garfo de colaboração privada.
Registro de aconselhamento: GHSA- 4 pj 9 - g 833 - qx 53. Identificadores relacionados: CVE- 2026 - 46428.
Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 28 T 14: 29: 10.000 Z e lista a sua última modificação como 2026 - 07 - 28 T 14: 29: 10.000 Z.
Gravidade: Crítico. Dados de pontuação publicados: CVSS_V 4: CVSS: 4.0 /AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:L/SI:L/África do Sul:N.
Software afetado e informações de versão: caixas.io pacote letra — ECOSISTEM: introduzido 0.10.1, corrigido 0.11.22.
Classificação e evidência: identificadores de fraqueza CWE- 295. O registro contém 6 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.