Validate SMTP server certificate on STARTTLS upgrade#65346
Merged
potiuk merged 2 commits intoapache:mainfrom Apr 16, 2026
Merged
Validate SMTP server certificate on STARTTLS upgrade#65346potiuk merged 2 commits intoapache:mainfrom
potiuk merged 2 commits intoapache:mainfrom
Conversation
smtplib.SMTP.starttls() does not validate the server certificate unless an SSL context is passed. airflow.utils.email.send_mime_email and the SMTP provider's SmtpHook (both sync get_conn and async aget_conn) were calling starttls() without a context, so the STARTTLS upgrade accepted any certificate and the subsequent login() call could send credentials over a connection terminated by a MITM. Pass the existing SSL-context machinery (the email.ssl_context config in core and the ssl_context connection extra in the provider) to starttls() at all three call sites. The default becomes ssl.create_default_context(), which validates against the system's trusted CAs. Users who intentionally use self-signed certificates can still opt out by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
Document the default behaviour change introduced by passing an SSL context to the STARTTLS upgrade: system-default CA validation now applies to both airflow.utils.email.send_email (via email.ssl_context) and the SMTP provider's SmtpHook (via the ssl_context connection extra). Users who intentionally run against self-signed SMTP servers can preserve the old behaviour by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
eladkal
reviewed
Apr 16, 2026
eladkal
approved these changes
Apr 16, 2026
Contributor
|
Hi maintainer, this PR was merged without a milestone set.
|
github-actions Bot
pushed a commit
that referenced
this pull request
Apr 16, 2026
) * Validate SMTP server certificate on STARTTLS upgrade smtplib.SMTP.starttls() does not validate the server certificate unless an SSL context is passed. airflow.utils.email.send_mime_email and the SMTP provider's SmtpHook (both sync get_conn and async aget_conn) were calling starttls() without a context, so the STARTTLS upgrade accepted any certificate and the subsequent login() call could send credentials over a connection terminated by a MITM. Pass the existing SSL-context machinery (the email.ssl_context config in core and the ssl_context connection extra in the provider) to starttls() at all three call sites. The default becomes ssl.create_default_context(), which validates against the system's trusted CAs. Users who intentionally use self-signed certificates can still opt out by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Add newsfragment and SMTP provider changelog for STARTTLS cert default Document the default behaviour change introduced by passing an SSL context to the STARTTLS upgrade: system-default CA validation now applies to both airflow.utils.email.send_email (via email.ssl_context) and the SMTP provider's SmtpHook (via the ssl_context connection extra). Users who intentionally run against self-signed SMTP servers can preserve the old behaviour by setting the value to "none". (cherry picked from commit 06981d4) Co-authored-by: Jarek Potiuk <jarek@potiuk.com> Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
Backport successfully created: v3-2-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
github-actions Bot
pushed a commit
to aws-mwaa/upstream-to-airflow
that referenced
this pull request
Apr 16, 2026
…che#65346) * Validate SMTP server certificate on STARTTLS upgrade smtplib.SMTP.starttls() does not validate the server certificate unless an SSL context is passed. airflow.utils.email.send_mime_email and the SMTP provider's SmtpHook (both sync get_conn and async aget_conn) were calling starttls() without a context, so the STARTTLS upgrade accepted any certificate and the subsequent login() call could send credentials over a connection terminated by a MITM. Pass the existing SSL-context machinery (the email.ssl_context config in core and the ssl_context connection extra in the provider) to starttls() at all three call sites. The default becomes ssl.create_default_context(), which validates against the system's trusted CAs. Users who intentionally use self-signed certificates can still opt out by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Add newsfragment and SMTP provider changelog for STARTTLS cert default Document the default behaviour change introduced by passing an SSL context to the STARTTLS upgrade: system-default CA validation now applies to both airflow.utils.email.send_email (via email.ssl_context) and the SMTP provider's SmtpHook (via the ssl_context connection extra). Users who intentionally run against self-signed SMTP servers can preserve the old behaviour by setting the value to "none". (cherry picked from commit 06981d4) Co-authored-by: Jarek Potiuk <jarek@potiuk.com> Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
karenbraganz
pushed a commit
to karenbraganz/airflow
that referenced
this pull request
Apr 16, 2026
* Validate SMTP server certificate on STARTTLS upgrade smtplib.SMTP.starttls() does not validate the server certificate unless an SSL context is passed. airflow.utils.email.send_mime_email and the SMTP provider's SmtpHook (both sync get_conn and async aget_conn) were calling starttls() without a context, so the STARTTLS upgrade accepted any certificate and the subsequent login() call could send credentials over a connection terminated by a MITM. Pass the existing SSL-context machinery (the email.ssl_context config in core and the ssl_context connection extra in the provider) to starttls() at all three call sites. The default becomes ssl.create_default_context(), which validates against the system's trusted CAs. Users who intentionally use self-signed certificates can still opt out by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Add newsfragment and SMTP provider changelog for STARTTLS cert default Document the default behaviour change introduced by passing an SSL context to the STARTTLS upgrade: system-default CA validation now applies to both airflow.utils.email.send_email (via email.ssl_context) and the SMTP provider's SmtpHook (via the ssl_context connection extra). Users who intentionally run against self-signed SMTP servers can preserve the old behaviour by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 tasks
vatsrahul1001
pushed a commit
that referenced
this pull request
Apr 23, 2026
) * Validate SMTP server certificate on STARTTLS upgrade smtplib.SMTP.starttls() does not validate the server certificate unless an SSL context is passed. airflow.utils.email.send_mime_email and the SMTP provider's SmtpHook (both sync get_conn and async aget_conn) were calling starttls() without a context, so the STARTTLS upgrade accepted any certificate and the subsequent login() call could send credentials over a connection terminated by a MITM. Pass the existing SSL-context machinery (the email.ssl_context config in core and the ssl_context connection extra in the provider) to starttls() at all three call sites. The default becomes ssl.create_default_context(), which validates against the system's trusted CAs. Users who intentionally use self-signed certificates can still opt out by setting the value to "none". Generated-by: Claude Opus 4.6 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Add newsfragment and SMTP provider changelog for STARTTLS cert default Document the default behaviour change introduced by passing an SSL context to the STARTTLS upgrade: system-default CA validation now applies to both airflow.utils.email.send_email (via email.ssl_context) and the SMTP provider's SmtpHook (via the ssl_context connection extra). Users who intentionally run against self-signed SMTP servers can preserve the old behaviour by setting the value to "none". (cherry picked from commit 06981d4) Co-authored-by: Jarek Potiuk <jarek@potiuk.com> Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
smtplib.SMTP.starttls()does not validate the server certificate unless an SSL context is passed.airflow.utils.email.send_mime_emailand the SMTP provider'sSmtpHook(both syncget_connand asyncaget_conn) were callingstarttls()without a context, so the STARTTLS upgrade skipped certificate validation.This PR passes the existing SSL-context machinery to
starttls()at all three call sites:airflow-core/src/airflow/utils/email.py— factored the SSL-context lookup out of_get_smtp_connectioninto a helper_get_ssl_context(), driven by the existingemail.ssl_contextconfig. The helper is now called by both theSMTP_SSLpath and the new STARTTLS path.providers/smtp/src/airflow/providers/smtp/hooks/smtp.py— factored the SSL-context lookup into_build_ssl_context(), driven by the existingssl_contextconnection extra. The helper is called forSMTP_SSL(sync), foraiosmtplib.SMTPconstruction (async), and for the explicitstarttls()calls in bothget_connandaget_conn.Default behaviour change
The default SSL context is now
ssl.create_default_context(), which validates against the system's trusted CAs. Environments that intentionally use self-signed or otherwise non-validating SMTP servers can opt out:email.ssl_context = "none"inairflow.cfgssl_context: "none"in the SMTP connection extrasThe opt-out already existed for the SMTP_SSL path; it now applies to the STARTTLS path too.
Test plan
airflow-core/tests/unit/utils/test_email.py— 25/25 passproviders/smtp/tests/unit/smtp/hooks/test_smtp.py— 34/34 pass (including synctest_ehlo_called_after_starttlsand asynctest_async_connectionupdated to verifystarttlsis invoked with anssl.SSLContext)Was generative AI tooling used to co-author this PR?
Generated-by: Claude Opus 4.6 (1M context) following the guidelines at
https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions