pip with truststore and proxy can use incorrect ssl_context #13288
Labels
C: network connectivity
state: needs eyes
Needs a maintainer/triager to take a closer look
type: bug
A confirmed bug or unintended behavior
Description
Disclaimer:
I am not 100% sure if this issue is a bug in pip or rather requests or some other of the vendored library, but I am happy to work together to determine the right location and file the bug there.
Setup:
Linux with
HTTP_PROXY
andHTTPS_PROXY
set and pip25.0.1
on Python 3.10.Issue:
When running
python -m pip install <package>
I receive following error messages:Investigations on my side:
When setting
SSL_CERT_FILE
tocacert.pem
it works.Not being really happy with this workaround I did a debug session on pip and came up with this trail of events.
The truststore
ssl_context
is constructed here and then passed to thePipSession
.https://github.com/pypa/pip/blob/25.0.1/src/pip/_internal/cli/index_command.py#L95
Inside the
PipSession
either theHTTPAdapter
or theCacheControlAdapter
are used:https://github.com/pypa/pip/blob/25.0.1/src/pip/_internal/network/session.py#L294
For this case consider the no cache case, the issue happens in both cases. The
HTTPAdapter
here is a combination of the_SSLContextAdapterMixin
in the same file and the requestHTTPAdapter
. Thessl_context
is passed in the constructor to this, the requests class does not use this kwargs. It is used in the_SSLContextAdapterMixin
and stored for later use wheninit_poolmanager
is called.The
init_poolmanger
is called fromrequests
in the constructor:https://github.com/pypa/pip/blob/25.0.1/src/pip/_vendor/requests/adapters.py#L222
This set up
self.poolmanager
of the Adapter to a poolmanager that will use thessl_context
. This is done by saving it ìnside theurllib3
PoolManager
see here:https://github.com/pypa/pip/blob/25.0.1/src/pip/_vendor/urllib3/poolmanager.py#L173
When this adapter is used in
send
it will callget_connection_with_tls_context
https://github.com/pypa/pip/blob/25.0.1/src/pip/_vendor/requests/adapters.py#L633
Now we are approaching the issue location when in this location we use
build_connection_pool_key_attributes
to get thepool_kwargs
. This will use theself.poolmanager
(that was constructed before) in this location to get the kwargs:https://github.com/pypa/pip/blob/25.0.1/src/pip/_vendor/requests/adapters.py#L444
The logic in the lines here
https://github.com/pypa/pip/blob/25.0.1/src/pip/_vendor/requests/adapters.py#L104-L120
will check the given PoolManager if it has a
ssl_context
set and not define this as part of the kwargs (e.g. no the default ssl_context). But when returning to the previous location in the case of a set proxy we will "overwrite" the used PoolManager with a ProxyManager:https://github.com/pypa/pip/blob/25.0.1/src/pip/_vendor/requests/adapters.py#L527
As the
ssl_context
is not part of thepool_kwargs
it will not be considered for the ProxyManager and there is nossl_context
set even soverify
isTrue
.I did a quick sanity check by adding this command before the line 527 (where
conn
is created with the ProxyManger).And while this is not a proper workaround it still tests if when the
ssl_context
is propagated everything works. And with this change the same command in the same environment is working properly.Expected behavior
Pip will use truststore and system certificates and succesfully verify the PyPI certificates.
pip version
25.0.1
Python version
3.10
OS
Linux
How to Reproduce
I am not 100% sure I have completely understood how to reproduce it. So multiple requirements are:
But I am pretty sure this are not sufficient to reproduce and there is another requirement on the OpenSSL configuration used or similar. I will continue to investigate this and if I find more details add them here.
Output
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: