CVE-2026-7666 Overview
CVE-2026-7666 affects the Django web framework's SMTP email backend. The flaw resides in django.core.mail.backends.smtp.EmailBackend, which fails to prevent reuse of a partially-initialized connection after a failed STARTTLS handshake when fail_silently=True is set. On-path network attackers can intercept email content in cleartext by forcing the STARTTLS negotiation to fail. The Django team credits Kasper Dupont for reporting the issue. The vulnerability is classified under CWE-319: Cleartext Transmission of Sensitive Information.
Critical Impact
Email messages sent through Django's SMTP backend with fail_silently=True may be transmitted in cleartext after a failed STARTTLS handshake, exposing message contents to on-path attackers.
Affected Products
- Django 6.0 before 6.0.6
- Django 5.2 before 5.2.15
- Earlier unsupported series (5.0.x, 4.1.x, 3.2.x) were not evaluated and may also be affected
Discovery Timeline
- 2026-06-03 - CVE-2026-7666 published to NVD
- 2026-06-03 - Last updated in NVD database
- Reported to Django by Kasper Dupont
Technical Details for CVE-2026-7666
Vulnerability Analysis
Django's SMTP email backend negotiates an opportunistic TLS upgrade through the STARTTLS command before transmitting email contents. When the backend is configured with fail_silently=True, exceptions raised during connection setup are suppressed. The flaw arises when the STARTTLS handshake fails: the backend does not discard the partially-initialized connection. Subsequent email send operations reuse the cleartext SMTP socket. Email contents — including headers, recipients, and message bodies — then traverse the network unencrypted.
Root Cause
The root cause is improper error handling in the SMTP connection lifecycle. The EmailBackend treats a STARTTLS failure as a recoverable condition under fail_silently=True rather than tearing down the underlying socket. The connection object remains cached and is returned for later send_messages() calls. This violates the secure-by-default expectation that TLS-required configurations refuse to fall back to plaintext.
Attack Vector
An attacker positioned on the network path between the Django application and the SMTP server can interfere with the STARTTLS handshake. Common techniques include stripping the STARTTLS capability from the server greeting or injecting a TLS alert during negotiation. Once the handshake fails, the attacker passively observes subsequent SMTP traffic. The attack requires network-adjacent positioning and a specific application configuration (fail_silently=True), which limits practical exploitability but does not eliminate it in shared-infrastructure environments.
No public proof-of-concept code is currently available. The vulnerability mechanism is documented in the Django Weblog Security Release.
Detection Methods for CVE-2026-7666
Indicators of Compromise
- Outbound SMTP sessions from Django application hosts that begin with EHLO but never transition to a TLS-encrypted stream
- SMTP server logs showing successful MAIL FROM and DATA commands on port 25 or 587 without a preceding successful STARTTLS
- Network captures revealing email message bodies in cleartext between application servers and configured mail relays
Detection Strategies
- Inspect application code and settings for EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' combined with fail_silently=True and EMAIL_USE_TLS = True
- Deploy network sensors that alert when SMTP sessions to known mail relays complete without TLS upgrade
- Audit Django dependency manifests (requirements.txt, pyproject.toml, poetry.lock) for vulnerable Django versions
Monitoring Recommendations
- Monitor egress SMTP traffic for plaintext message content using deep packet inspection or zeek/suricata signatures
- Correlate Django application logs with SMTP relay logs to identify discrepancies between intended TLS use and actual transport security
- Enable verbose SMTP logging on outbound mail relays to record TLS negotiation outcomes per session
How to Mitigate CVE-2026-7666
Immediate Actions Required
- Upgrade Django to version 6.0.6 or 5.2.15 as published in the Django security release
- Audit application configurations for fail_silently=True usage in mail-sending code paths and remove it where TLS confidentiality is required
- Set EMAIL_USE_TLS = True or EMAIL_USE_SSL = True and verify SMTP relays enforce TLS at the server side
Patch Information
The Django project released fixes in Django 6.0.6 and Django 5.2.15 on June 3, 2026. Details and download links are available in the Django Security Releases Documentation and the Django Announcements Group. Unsupported Django series (5.0.x, 4.1.x, 3.2.x) have not been evaluated and will not receive patches; users on those branches should upgrade to a supported release.
Workarounds
- Configure outbound SMTP relays to require implicit TLS (SMTPS on port 465) instead of opportunistic STARTTLS, eliminating the downgrade window
- Remove fail_silently=True from send_mail(), mail_admins(), and EmailMessage.send() calls where email contents are sensitive
- Restrict outbound SMTP egress to a hardened internal relay that enforces TLS, reducing exposure to on-path attackers
# Upgrade Django to a patched release
pip install --upgrade 'Django>=6.0.6,<6.1'
# or for the 5.2 series
pip install --upgrade 'Django>=5.2.15,<5.3'
# Verify installed version
python -c "import django; print(django.get_version())"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


