Skip to content
New issue

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

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

Already on GitHub? # to your account

Move _get_connection to get_connection_with_tls_context #6710

Merged
merged 2 commits into from
May 21, 2024

Conversation

nateprewitt
Copy link
Member

@nateprewitt nateprewitt commented May 21, 2024

This PR is meant to provide a new publicly supported api get_connection_with_tls_context to better facilitate custom adapters with our recent fix for CVE-2024-35195.

As described here, we will be deprecating the existing get_connection API, and custom adapters will need to migrate their existing get_connection implementations to use get_connection_with_tls_context. Below is a very simple implementation that will get projects relying on a custom get_connection implementation unblocked.

However, we strongly recommend maintainers evaluate if their custom get_connection is subject to the same issues as the CVE above and make appropriate changes as needed.

Minimum new code to work as a pass-through
This will be backwards compatible between versions of Requests.

def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
    return self.get_connection(request.url, proxies)

@nateprewitt
Copy link
Member Author

cc @felixfontein

Copy link
Member

@sethmlarson sethmlarson left a comment

Choose a reason for hiding this comment

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

Looks good, only had one suggestion that might require a new test.

src/requests/adapters.py Show resolved Hide resolved
@kdymov
Copy link

kdymov commented May 23, 2024

A small update about the minimum pass-through code for someone who will stumble upon this - don’t forget to return the value, as you will face a different exception if you do 🙂

def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
    return self.get_connection(request.url, proxies)

simondeziel added a commit to simondeziel/pylxd that referenced this pull request May 23, 2024
simondeziel added a commit to simondeziel/pylxd that referenced this pull request May 23, 2024
requests 2.32 security fix recommends a fix:
psf/requests#6710

This was proposed (but not yet merged) to requests-unixsocket in:
msabramo/requests-unixsocket#72

Signed-off-by: Simon Deziel <simon.deziel@canonical.com>
@nateprewitt
Copy link
Member Author

Thank you @kdymov! I've fixed the initial example as well.

@WhyNotHugo
Copy link
Contributor

I'm having some issues upgrading to requests 2.32 which I think are related to this change, but I can't quite figure out how I'd need to upgrade my code.

My HTTPAdapter subclass basically overrides the TLS context to allow weak DH ciphers:

class AFIPAdapter(HTTPAdapter):
    """An adapter with reduced security so it'll work with AFIP."""

    def init_poolmanager(self, *args, **kwargs) -> PoolManager:
        context = create_urllib3_context(ciphers=CIPHERS)
        kwargs["ssl_context"] = context
        return super().init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs) -> ProxyManager:
        context = create_urllib3_context(ciphers=CIPHERS)
        kwargs["ssl_context"] = context
        return super().proxy_manager_for(*args, **kwargs)

With requests==2.31.0 this works, but with requests==2.32.0 it doesn't. I keep re-reading the changes in this patchset and can't fully grasp how they're affecting me.

Do you have any guidance?

@WhyNotHugo
Copy link
Contributor

I'm also a bit confused by get_connection_with_tls_context, because it reads Returns a urllib3 connection for the given request and TLS settings, but no TLS settings are given.

@nateprewitt
Copy link
Member Author

@WhyNotHugo You may be hitting a separate issue with init_poolmanager. We just released 2.32.3 to address that problem with custom adapters, you may want to give that a try.

@WhyNotHugo
Copy link
Contributor

2.32.3 raises an entirely different exception:

requests.exceptions.SSLError: HTTPSConnectionPool(host='wswhomo.afip.gov.ar', port=443): Max retries exceeded with url: /wsfev1/service.asmx (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)')))

@WhyNotHugo
Copy link
Contributor

Looks like I need to add context.load_default_certs() and it works fine. It wasn't required before tho.

WhyNotHugo added a commit to WhyNotHugo/django-afip that referenced this pull request May 29, 2024
@nateprewitt
Copy link
Member Author

We may not be loading the cert bundle the same as we were previously. Would you mind opening a new issue with a minimal reproduction (the adapter you have above is likely fine). If you can also include the info we request from help, and if you're working behind a proxy when this happens. That'd be helpful, thanks!

derekpierre added a commit to derekpierre/nucypher that referenced this pull request Jul 16, 2024
AdamWill added a commit to AdamWill/httpie-cli that referenced this pull request Sep 4, 2024
…e#1583)

Requests prior to 2.32.3 always loaded the default (system-wide)
set of trusted certificates into custom SSL contexts. 2.32.3 no
longer does. This has broken a lot of users, but the fix is
moving slowly upstream due to security considerations - see
psf/requests#6730 and
psf/requests#6731 .

As suggested at
psf/requests#6710 (comment)
this can be worked around by explicitly loading the default
certificates into the context. We check the method exists before
calling it just to be safe, but I'm pretty sure it's been there
as long as this interface has existed.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
AdamWill added a commit to AdamWill/httpie-cli that referenced this pull request Sep 4, 2024
…e#1583)

Requests prior to 2.32.3 always loaded the default (system-wide)
set of trusted certificates into custom SSL contexts. 2.32.3 no
longer does. This has broken a lot of users, but the fix is
moving slowly upstream due to security considerations - see
psf/requests#6730 and
psf/requests#6731 .

As suggested at
psf/requests#6710 (comment)
this can be worked around by explicitly loading the default
certificates into the context. We check the method exists before
calling it just to be safe, but I'm pretty sure it's been there
as long as this interface has existed.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
AdamWill added a commit to AdamWill/httpie-cli that referenced this pull request Sep 6, 2024
…e#1583)

Requests prior to 2.32.3 always loaded the default (system-wide)
set of trusted certificates into custom SSL contexts. 2.32.3 no
longer does. This has broken a lot of users, but the fix is
moving slowly upstream due to security considerations - see
psf/requests#6730 and
psf/requests#6731 .

As suggested at
psf/requests#6710 (comment)
this can be worked around by explicitly loading the default
certificates into the context. We check the method exists before
calling it just to be safe, it was added in Python 3.4.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
millerdev added a commit to dimagi/commcare-hq that referenced this pull request Nov 1, 2024
jkbrzt pushed a commit to httpie/cli that referenced this pull request Nov 1, 2024
#1596)

* Explicitly load default certificates when creating SSL context (#1583)

Requests prior to 2.32.3 always loaded the default (system-wide)
set of trusted certificates into custom SSL contexts. 2.32.3 no
longer does. This has broken a lot of users, but the fix is
moving slowly upstream due to security considerations - see
psf/requests#6730 and
psf/requests#6731 .

As suggested at
psf/requests#6710 (comment)
this can be worked around by explicitly loading the default
certificates into the context. We check the method exists before
calling it just to be safe, it was added in Python 3.4.

Signed-off-by: Adam Williamson <awilliam@redhat.com>

* Drop the upper bound on the requests dependency again

As we can now work with requests 2.32.3+, we no longer need this
pin.

Signed-off-by: Adam Williamson <awilliam@redhat.com>

---------

Signed-off-by: Adam Williamson <awilliam@redhat.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants