Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft PEP: Enabling certificate verification by default for stdlib mail modules #3602

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,7 @@ peps/pep-0733.rst @encukou @vstinner @zooba @iritkatriel
peps/pep-0734.rst @ericsnowcurrently
peps/pep-0735.rst @brettcannon
peps/pep-0737.rst @vstinner
#peps/pep-0738.rst
# ...
# peps/pep-0754.rst
# ...
Expand Down
97 changes: 97 additions & 0 deletions peps/pep-0738.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
PEP: 738
Title: Enabling certificate verification by default for stdlib mail modules
Author: Martin Schobert <[email protected]>
Status: Draft
Type: Standards Track
Created: 17-Nov-2023

Abstract
=========

The Python mail libraries such as ``smtplib``, ``imaplib`` and ``pop3lib``
do not verify server certificates per default, when a client based on these
mail libraries connects to a server via TLS. Any server certificate is
accepted per default. This means, a client can't ensure that it connects
to the server to which the connection was intended.

This allows an active attacker in a machine-in-the-middle postion to intercept
communication, read mail contents, credentials or may abuse an SMTP server
for spaming.

Motivation
===========

This PEP proposes to enable verification of X509 certificates for Python's
mail clients by default, subject to opt-out on a per-call basis. This change
would be applied to all maintained Python versions.
Comment on lines +24 to +26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like the abstract! And what you wrote in the abstract sounds like the motivation. :-)


Rationale
=========

It can be expected that a Python mail client, written in the most simple way, is
secure by default. If progam code wants to insecurely connect to a server, this
action should require and explicit confirmation. Not verifying a server certificate
and accepting it violates PEP 20's principle "errors should never pass silently."

It can also be expected that Python standard libraries behave in a consitent way.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consistent

While Python's HTTP stdlib modules verify server certificates per default after
implementing the change request from PEP 476, developers may expect Python mail
libraries to behave similar.

The failure of various applications to note Python's negligence in this matter
is a source of vulnerabilities [#]_ [#]_ [#]_ [#]_.

.. [#] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-39441
.. [#] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-38686
.. [#] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-39441
.. [#] https://www.pentagrid.ch/en/blog/python-mail-libraries-certificate-verification/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which IIUC you wrote.


Specification
=================

Python would use the system provided certificate database on all platforms.
Failure to locate such a database would be an error, and users would need to
explicitly specify a location to fix it.

Python will change the ``_create_stdlib_context`` as default context in the
mail libraries with ``ssl.create_default_context``.

If a developer wants to disable certificate verification, an explicitly created
SSL/TLS context may be passed that has been created with ``_create_unverified_context``.

Trust database
--------------

This PEP proposes using the system-provided certificate database.


Opting out
----------

For users who wish to opt out of certificate verification on a single
connection, they can achieve this by providing the ``ssl_context``
for ``imaplib.IMAP4_SSL`` respectively ``context`` for ``smtplib.SMTP_SSL`` and
``poplib.POP3_SSL``.


Backwards compatibility
=======================

This change may result in failed connections, when servers do not use
valid and trusted certificates. With invalid or untrusted certificates, the Python
TLS library will raise an exception during TLS handshake.

Nevertheless, this will only happen with invalid mail server certificates or
server certificates that do not rely on a trust anchor known to Python's
runtime environment. In these cases it is necessary that the system admin
either installs a valid mail server certificate or the client ensures
there is a trust anchor defined (a valid certificate chain leading from a CA
file to the server certificate). As an unrecommended alternative, the client
code may use an SSL context that does not verify certificates as descibed
in the next section.

Copyright
=========

This document is placed in the public domain or under the
CC0-1.0-Universal license, whichever is more permissive.