CVE-2026-46428 Overview
CVE-2026-46428 is a certificate validation flaw [CWE-295] in lettre, a mailer library for Rust. Versions from 0.10.1 up to but not including 0.11.22 contain an inverted-boolean bug in the boring-tls integration. The defect silently disables TLS hostname verification for callers relying on the default strict configuration. An on-path attacker presenting any chain-valid certificate for any domain can intercept SMTP submission traffic. Intercepted data includes PLAIN and LOGIN authentication credentials as well as message contents. The native-tls and rustls backends are unaffected. Version 0.11.22 patches the issue.
Critical Impact
Any Rust application built with the boring-tls feature of lettre between 0.10.1 and 0.11.21 accepts fraudulent TLS certificates, enabling credential theft and SMTP traffic interception by network-positioned adversaries.
Affected Products
- lettre crate versions 0.10.1 through 0.11.21 (built with the boring-tls or tokio1-boring-tls feature)
- Rust applications sending SMTP through lettre with BoringSSL as the TLS backend
- Downstream services performing SMTP submission with PLAIN or LOGIN authentication over boring-tls
Discovery Timeline
- 2026-07-20 - CVE-2026-46428 published to NVD
- 2026-07-23 - Last updated in NVD database
Technical Details for CVE-2026-46428
Vulnerability Analysis
The defect lives in the SMTP client's TLS setup code paths for the boring-tls and tokio1-boring-tls features. The library exposes an accept_invalid_hostnames option that callers set to false by default to enforce strict hostname validation. When configuring the BoringSSL connector, lettre passed this flag directly to set_verify_hostname and verify_hostname. Those BoringSSL APIs expect the opposite semantics: true enables verification. Passing false disabled hostname verification for every caller using default, secure settings. The result is a silent TLS trust decision that never surfaces an error at connection time.
Root Cause
The root cause is a boolean polarity error, an instance of improper certificate validation [CWE-295]. lettre treated accept_invalid_hostnames as if it meant verify_hostname. Because both APIs accept a bool, the compiler could not catch the semantic mismatch. Certificate chain validation still functioned, so mis-issued or attacker-owned certificates for unrelated domains passed the reduced check.
Attack Vector
An attacker positioned on the network path between the lettre client and its configured SMTP relay presents any TLS certificate that chains to a trusted root, regardless of the certificate's subject. The lettre client establishes the TLS session, sends AUTH PLAIN or AUTH LOGIN credentials, and transmits message contents. The attacker captures credentials and mail contents and can relay traffic to the real SMTP server to remain undetected.
// Patch: src/transport/smtp/client/async_net.rs
#[cfg(feature = "tokio1-boring-tls")]
return {
let mut config = connector.configure().map_err(error::connection)?;
- config.set_verify_hostname(accept_invalid_hostnames);
+ config.set_verify_hostname(!accept_invalid_hostnames);
let stream = tokio1_boring::connect(config, &domain, tcp_stream)
.await
};
// Patch: src/transport/smtp/client/net.rs
let stream = connector
.configure()
.map_err(error::connection)?
- .verify_hostname(*accept_invalid_hostnames)
+ .verify_hostname(!*accept_invalid_hostnames)
.connect(tls_parameters.domain(), tcp_stream)
.map_err(error::connection)?;
InnerNetworkStream::BoringTls(stream);
Source: GitHub commit f5efffc
Detection Methods for CVE-2026-46428
Indicators of Compromise
- SMTP submission connections completing successfully to unexpected IP addresses or autonomous systems for the configured mail relay hostname.
- TLS sessions to the SMTP relay presenting certificates whose Subject Alternative Name does not match the configured relay hostname.
- Unexplained authentication events on the SMTP submission service originating from clients running lettre with boring-tls.
Detection Strategies
- Inventory Rust projects by scanning Cargo.lock files for lettre versions between 0.10.1 and 0.11.21 with the boring-tls or tokio1-boring-tls feature enabled.
- Compare TLS certificate fingerprints observed on outbound SMTP submission (ports 465 and 587) against the expected fingerprint of the configured mail relay.
- Enable SMTP audit logging on the mail submission service and alert on client TLS SNI values that do not match the server's certificate identity.
Monitoring Recommendations
- Continuously monitor egress on TCP 465 and 587 from application hosts and flag connections to destinations outside the sanctioned mail relay allowlist.
- Log outbound TLS metadata (SNI, certificate subject, issuer, fingerprint) from application servers using lettre and alert on unexpected issuers.
- Track dependency drift in CI/CD pipelines and gate builds that include vulnerable lettre versions.
How to Mitigate CVE-2026-46428
Immediate Actions Required
- Upgrade lettre to version 0.11.22 in all Rust projects and rebuild affected binaries.
- Rotate any SMTP submission credentials that may have transited a vulnerable lettre client, including passwords for PLAIN and LOGIN mechanisms.
- Audit dependency trees with cargo tree -i lettre to confirm no transitive dependency pins a vulnerable version.
Patch Information
The fix is released in lettre 0.11.22. It negates the accept_invalid_hostnames flag before passing it to BoringSSL's set_verify_hostname and verify_hostname APIs. Reference the GitHub Security Advisory GHSA-4pj9-g833-qx53, RustSec Advisory RUSTSEC-2026-0141, and the v0.11.22 release notes.
Workarounds
- Switch the TLS backend to native-tls or rustls by adjusting the lettre feature flags in Cargo.toml until upgrading is feasible.
- Restrict outbound SMTP submission to a locally trusted relay reached over a network path the operator controls, reducing on-path attacker opportunities.
- Pin outbound SMTP endpoints to specific certificate fingerprints at a network proxy that terminates and re-establishes TLS.
# Update Cargo.toml to the patched version
# [dependencies]
# lettre = { version = "0.11.22", default-features = false, features = ["smtp-transport", "tokio1-boring-tls"] }
cargo update -p lettre --precise 0.11.22
cargo tree -i lettre | grep -E "0\.1(0\.[1-9]|1\.([0-9]|1[0-9]|2[01]))"
cargo audit
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

