Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-107361: strengthen default SSL context flags#112389

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

woodruffw
Copy link
Contributor

@woodruffwwoodruffw commentedNov 25, 2023
edited by github-actionsbot
Loading

See#107361: this addsVERIFY_X509_STRICT to make the default SSL context perform stricter (per RFC 5280) validation, as well asVERIFY_X509_PARTIAL_CHAIN to enforce more standards-compliant path-building behavior.

As part of this changeset, I had to tweakmake_ssl_certs.py slightly to emit 5280-conforming CA certs. This changeset includes the regenerated certificates after that change.

CC@sethmlarson


📚 Documentation preview 📚:https://cpython-previews--112389.org.readthedocs.build/

Seepython#107361: this adds `VERIFY_X509_STRICT` to make the defaultSSL context perform stricter (per RFC 5280) validation, as wellas `VERIFY_X509_PARTIAL_CHAIN` to enforce more standards-compliantpath-building behavior.As part of this changeset, I had to tweak `make_ssl_certs.py`slightly to emit 5280-conforming CA certs. This changeset includesthe regenerated certificates after that change.
@sethmlarsonsethmlarson added the type-securityA security issue labelNov 25, 2023
@gpsheadgpshead self-assigned thisNov 29, 2023
@bedevere-app
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phraseI have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

And if you don't make the requested changes, you will be poked with soft cushions!

@pitrou
Copy link
Member

Side note: perhaps we mark all PEM files asgenerated?

Signed-off-by: William Woodruff <william@yossarian.net>
Signed-off-by: William Woodruff <william@yossarian.net>
Signed-off-by: William Woodruff <william@yossarian.net>
Signed-off-by: William Woodruff <william@yossarian.net>
@woodruffw
Copy link
ContributorAuthor

Side note: perhaps we mark all PEM files asgenerated?

Done: I've markedcertdata/*.{pem,0} as generated (the.0 files should also really be.pem I think -- I can do some cleanup there in a follow-up PR, if there's interest).

@vstinner
Copy link
Member

In practice, this should have no effect on >99% of users: most root programs use 5280 as their baseline, and the Web PKI's CABF rules are also built on 5280.

Your PR required to regenerate all PEM test certificates. Does it mean that they belong to the 1% of affected users?

@woodruffw
Copy link
ContributorAuthor

Your PR required to regenerate all PEM test certificates. Does it mean that they belong to the 1% of affected users?

I made the numbers up for emphasis, but I'll stand by this having no effect on the vast majority of users: the vast majority use case is the Web PKI, which is significantly stricter than evenVERIFY_X509_STRICT. The fact that the PEMs had to be regenerated is more a testament to how lax OpenSSL is by default than any actual common practice 🙂

Or put another way: most users are not manually generating certs withopenssl req or, if they are, they're massaging them into RFC 5280 compliance because other ecosystems (like Go, Java, and OSes/major software) are much more strict.

Additional datapoints:

(I picked these semi-arbitrarily fromhttps://pkic.org/ltl/)

pitrou reacted with thumbs up emoji

Copy link
Contributor

@sethmlarsonsethmlarson left a comment
edited
Loading

Choose a reason for hiding this comment

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

I'm ++ on the partial chain changes, my comments below apply toVERIFY_X509_STRICT:

Since OpenSSL will likely be the way folks are generating certificates and like you said, OpenSSL allows you to do things that isn't acceptable for Web PKI, is there any value in providing guidance on how one does generate a certificate with OpenSSL that works withVERIFY_X509_STRICT?

Also since we're recommending folks down a new code path to restore old behavior, should we create a new test which exercises that code path and verifies that "bad" certificates would be accepted?

What about non-Web PKI, does this change have any affect for certificates in that domain? I am less versed for this, so am relying a bit on others' experience.

gpshead reacted with thumbs up emoji
@pitrou
Copy link
Member

Since OpenSSL will likely be the way folks are generating certificates

Is that still the case? Aren't most users relying on something like Let's Encrypt nowadays (at least for Web certificates, but also perhaps e-mail)?

is there any value in providing guidance on how one does generate a certificate with OpenSSL that works withVERIFY_X509_STRICT?

I don't think writing an OpenSSL command line tutorial is really a responsibility for CPython maintainers.

woodruffw reacted with thumbs up emoji

@woodruffw
Copy link
ContributorAuthor

Since OpenSSL will likely be the way folks are generating certificates and like you said, OpenSSL allows you to do things that isn't acceptable for Web PKI, is there any value in providing guidance on how one does generate a certificate with OpenSSL that works with VERIFY_X509_STRICT?

To clarify: I think most userswon't be using OpenSSL to generate certs -- I think the majority will be getting their certs from a CA service (like Let's Encrypt), with a very small minority doing bespoke things. Putting an OpenSSL example in the docs might cause additional confusion, and IMO won't be too helpful anyways (since the context here is verification, in which case the user might not have any control over the certs they're being presented with).

What about non-Web PKI, does this change have any affect for certificates in that domain? I am less versed for this, so am relying a bit on others' experience

Nope, this should be wholly compatible with those -- "strict" validation for OpenSSL means "approximate RFC 5280," and the Web PKI profiles are a superset of RFC 5280 🙂

In other words: all public web certificates should be compatible with these changes.

pitrou and gpshead reacted with thumbs up emoji

@malemburg
Copy link
Member

These are the checks that OpenSSL applies when VERIFY_X509_STRICT is set:https://www.openssl.org/docs/man3.0/man1/openssl-verification-options.html#x509_strict (search for -x509_strict in case the link doesn't take you there directly)

These checks all make sense for certs generated with a trusted CA, e.g. Let's Encrypt.

The other common use case is having self-signed certs (e.g. for intranet/VPC devices). Those will already fail to verify with the current standard settings, since self-signed certs are rejected by OpenSSL's verify. You have to use thessl._create_unverified_context() or a custom one to the same effect for those.

Note: The POP/FTP/IMAP and SMTP modules use the unverified context, since intranet/VPC mail and FTP servers will often not use certs created by a trusted CA for various reasons or they are referenced using IP addresses, which don't work with certs at all.

@woodruffw
Copy link
ContributorAuthor

woodruffw commentedFeb 2, 2024
edited
Loading

I'm a little mystified by this error, which only happens on OpenSSL 1.1.1w in CI:

 0:00:10 load avg: 2.63 [18/43/1] test_ssl failed (1 failure)test test_ssl failed -- Traceback (most recent call last):  File "/home/runner/work/cpython/cpython/Lib/test/test_ssl.py", line 2971, in test_verify_strict    with self.assertRaises(ssl.SSLError):        s.connect((HOST, server.port))AssertionError: SSLError not raised

AFAICT, the strict flag exists in that version and has the same semantics as in OpenSSL 3.0 and 3.1, which both pass.

Edit: This is probably why:openssl/openssl@1e41dad (andopenssl/openssl#10688)

@woodruffw
Copy link
ContributorAuthor

This should be good to go again: I've added a "backstop" test that confirms thatVERIFY_X509_STRICT enables and disables as expected.

Copy link
Contributor

@sethmlarsonsethmlarson left a comment

Choose a reason for hiding this comment

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

LGTM, apologies for the delay!

woodruffw reacted with heart emoji
@woodruffw
Copy link
ContributorAuthor

LGTM, apologies for the delay!

It's "only" 3 months late on my end, so no hard feelings 😉

sethmlarson reacted with heart emoji

@ghost
Copy link

ghost commentedMar 4, 2024
edited by ghost
Loading

All commit authors signed the Contributor License Agreement.
CLA signed

@woodruffwwoodruffwforce-pushed thedefault-ssl-verify-flags branch from050b4eb to1a3e037CompareMarch 4, 2024 19:08
…flagsSigned-off-by: William Woodruff <william@yossarian.net>
@woodruffw
Copy link
ContributorAuthor

Gentle ping on this! I've deconflicted the changelog again.

@gpsheadgpshead added the 🔨 test-with-buildbotsTest PR w/ buildbots; report in status section labelMar 6, 2024
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by@gpshead for commitcef6950 🤖

If you want to schedule another build, you need to add the🔨 test-with-buildbots label again.

@bedevere-botbedevere-bot removed the 🔨 test-with-buildbotsTest PR w/ buildbots; report in status section labelMar 6, 2024
Copy link
Member

@gpsheadgpshead left a comment

Choose a reason for hiding this comment

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

LGTM - I'm just running a round of buildbot tests to look for any surprises before merging.

woodruffw reacted with heart emoji
…flagsSigned-off-by: William Woodruff <william@yossarian.net>
@gpsheadgpshead merged commit0876b92 intopython:mainMar 6, 2024
@woodruffwwoodruffw deleted the default-ssl-verify-flags branchMarch 6, 2024 21:47
adorilson pushed a commit to adorilson/cpython that referenced this pull requestMar 25, 2024
This adds `VERIFY_X509_STRICT` to make the defaultSSL context perform stricter (per RFC 5280) validation, as wellas `VERIFY_X509_PARTIAL_CHAIN` to enforce more standards-compliantpath-building behavior.As part of this changeset, I had to tweak `make_ssl_certs.py`slightly to emit 5280-conforming CA certs. This changeset includesthe regenerated certificates after that change.Signed-off-by: William Woodruff <william@yossarian.net>Co-authored-by: Victor Stinner <vstinner@python.org>
@sethmlarson
Copy link
Contributor

@woodruffw Looks like this change breaks trustme generated certificates, seepython-trio/trustme#642

@woodruffw
Copy link
ContributorAuthor

@woodruffw Looks like this change breaks trustme generated certificates, seepython-trio/trustme#642

Thanks for sharing! Looking now.

@vstinner
Copy link
Member

@woodruffw Looks like this change breaks trustme generated certificates, seepython-trio/trustme#642

If an application is affected by these changes, they can "just" disable the two options, no?

Usingctx.verify_flags &= ~(ssl.VERIFY_X509_STRICT | ssl.VERIFY_X509_PARTIAL_CHAIN):

$ ./pythonPython3.13.0a5+ (heads/main:b44898299a2,Mar282024,09:01:21) [GCC13.2.120240316 (RedHat13.2.1-7)]onlinux>>>importssl>>>ctx=ssl.create_default_context()>>>ctx.verify_flags&ssl.VERIFY_X509_STRICT<VerifyFlags.VERIFY_X509_STRICT:32>>>>ctx.verify_flags&ssl.VERIFY_X509_PARTIAL_CHAIN<VerifyFlags.VERIFY_X509_PARTIAL_CHAIN:524288>>>>ctx.verify_flags&=~(ssl.VERIFY_X509_STRICT|ssl.VERIFY_X509_PARTIAL_CHAIN)>>>ctx.verify_flags&ssl.VERIFY_X509_STRICT<VerifyFlags.VERIFY_DEFAULT:0>>>>ctx.verify_flags&ssl.VERIFY_X509_PARTIAL_CHAIN<VerifyFlags.VERIFY_DEFAULT:0>

@woodruffw
Copy link
ContributorAuthor

If an application is affected by these changes, they can "just" disable the two options, no?

Yep, correct. I think the above is also generating certs, so they wanted to get it right more generally, so that each Python downstream consumer doesn't have to also download the strict option.

diegorusso pushed a commit to diegorusso/cpython that referenced this pull requestApr 17, 2024
This adds `VERIFY_X509_STRICT` to make the defaultSSL context perform stricter (per RFC 5280) validation, as wellas `VERIFY_X509_PARTIAL_CHAIN` to enforce more standards-compliantpath-building behavior.As part of this changeset, I had to tweak `make_ssl_certs.py`slightly to emit 5280-conforming CA certs. This changeset includesthe regenerated certificates after that change.Signed-off-by: William Woodruff <william@yossarian.net>Co-authored-by: Victor Stinner <vstinner@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@vstinnervstinnervstinner left review comments

@gpsheadgpsheadgpshead approved these changes

@malemburgmalemburgmalemburg approved these changes

@sethmlarsonsethmlarsonsethmlarson approved these changes

Assignees

@gpsheadgpshead

Labels
type-securityA security issue
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

7 participants
@woodruffw@pitrou@vstinner@malemburg@sethmlarson@bedevere-bot@gpshead

[8]ページ先頭

©2009-2025 Movatter.jp