CVE-2023-38686: Improper Certificate Validation (CWE-295)
value: Sydent is an identity server for the Matrix communications protocol. Prior to version 2.5.6, if configured to send emails using TLS, Sydent does not verify SMTP servers' certificates. This makes  Sydent's emails vulnerable to interception via a man-in-the-middle (MITM) attack. Attackers with privileged access to the network can intercept room invitations and address confirmation emails. This is patched in Sydent 2.5.6. When patching, make sure that Sydent trusts the certificate of the server it is connecting to. This should happen automatically when using properly issued certificates. Those who use self-signed certificates should make sure to copy their Certification Authority certificate, or their self signed certificate if using only one, to the trust store of your operating system. As a workaround, one can ensure Sydent's emails fail to send by setting the configured SMTP server to a loopback or non-routable address under one's control which does not have a listening SMTP server.
CWE description: The product does not validate, or incorrectly validates, a certificate.
CVSS v3 base score: 5.3
Published: 2023-08-04T16:15Z
Repository: https://github.com/matrix-org/sydent
Language: Python
Files changed: changelog.d/574.bugfix, sydent/util/emailutils.py
Commit date: 2023-07-31 11:21:28 +0100
Commit message: Explicitly create an SSL context when emailing (#574)


Diff: diff --git a/changelog.d/574.bugfix b/changelog.d/574.bugfix
new file mode 100644
index 00000000..3dee1fbd
--- /dev/null
+++ b/changelog.d/574.bugfix
@@ -0,0 +1 @@
+Fix a long-standing issue where Sydent would not verify the configured SMTP server's certificates. See [GHSA-p6hw-wm59-3q5q](https://github.com/matrix-org/sydent/security/advisories/GHSA-p6hw-wm59-3g5g) and [CVE-2023-38686](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-38686). Reported by Martin Schobert, [Pentagrid AG](https://pentagrid.ch).
\ No newline at end of file
diff --git a/sydent/util/emailutils.py b/sydent/util/emailutils.py
index e202b7ad..5ad9b35a 100644
--- a/sydent/util/emailutils.py
+++ b/sydent/util/emailutils.py
@@ -14,10 +14,11 @@
 
 import email.utils
 import logging
 import random
 import smtplib
+import ssl
 import string
 import urllib
 from html import escape
 from typing import TYPE_CHECKING, Dict
 
@@ -104,15 +105,18 @@ def sendEmail(
             mailServer,
         )
     )
     try:
         smtp: smtplib.SMTP
+        # Explicitly create a context, to ensure we verify the server's certificate
+        # and hostname.
+        ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
         if mailTLSMode == "SSL" or mailTLSMode == "TLS":
-            smtp = smtplib.SMTP_SSL(mailServer, mailPort, myHostname)
+            smtp = smtplib.SMTP_SSL(mailServer, mailPort, myHostname, context=ctx)
         elif mailTLSMode == "STARTTLS":
             smtp = smtplib.SMTP(mailServer, mailPort, myHostname)
-            smtp.starttls()
+            smtp.starttls(context=ctx)
         else:
             smtp = smtplib.SMTP(mailServer, mailPort, myHostname)
         if mailUsername != "":
             smtp.login(mailUsername, mailPassword)
 

Vulnerable code:             smtp = smtplib.SMTP_SSL(mailServer, mailPort, myHostname)
            smtp.starttls()
Fixed code: Fix a long-standing issue where Sydent would not verify the configured SMTP server's certificates. See [GHSA-p6hw-wm59-3q5q](https://github.com/matrix-org/sydent/security/advisories/GHSA-p6hw-wm59-3g5g) and [CVE-2023-38686](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-38686). Reported by Martin Schobert, [Pentagrid AG](https://pentagrid.ch).
import ssl
        # Explicitly create a context, to ensure we verify the server's certificate
        # and hostname.
        ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
            smtp = smtplib.SMTP_SSL(mailServer, mailPort, myHostname, context=ctx)
            smtp.starttls(context=ctx)