I have a request like this from aiohttp:
async with aiohttp.ClientSession(auth=aiohttp.BasicAuth(self.user, self.password), timeout=aiohttp.ClientTimeout(connect=self.timeouts[0], sock_read=self.timeouts[1])) as session:
async with session.post(self.endpoint, data=query.encode('utf-8'), headers={'content-type' : 'application/xml'}, ssl=False) as response:
response.raise_for_status()
return await response.text()
The server being requested has an SSL certificate, but the certificate is "bad", unfortunately this is a problem with the software we have to work with. So ssl=False
is used to disable certificate verification.
On Python 3.7.9 this code worked without problems, but when upgrading to Python 3.12.3 an SSL Verification error started to occur at this point.
Traceback (most recent call last):
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1116, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs, sock=sock)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python312\Lib\asyncio\base_events.py", line 1149, in create_connection
transport, protocol = await self._create_connection_transport(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python312\Lib\asyncio\base_events.py", line 1182, in _create_connection_transport
await waiter
File "C:\Program Files\Python312\Lib\asyncio\sslproto.py", line 578, in _on_handshake_complete
raise handshake_exc
File "C:\Program Files\Python312\Lib\asyncio\sslproto.py", line 560, in _do_handshake
self._sslobj.do_handshake()
File "C:\Program Files\Python312\Lib\ssl.py", line 917, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\dev\my_project\server\controllers\rkeeper_cacher\update_task.py", line 38, in rkeeper_cacher_updater
await _wait_with_raise(tasks)
File "c:\dev\my_project\server\controllers\rkeeper_cacher\update_task.py", line 17, in _wait_with_raise
future.result()
File "c:\dev\my_project\server\controllers\rkeeper_cacher\service.py", line 124, in update_ref_if_need
if cache_version == -1 or cache_version != await self._get_ref_version(args.rk_ref_name):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\server\controllers\rkeeper_cacher\service.py", line 58, in _get_ref_version
xml = await self.rk_client.send(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\server\ext\rk7_api\async_client\client.py", line 35, in send
return await self.send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\server\ext\rk7_api\async_client\client.py", line 24, in send_command
return await self.send_xml(command._serialize())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\server\ext\rk7_api\async_client\client.py", line 12, in send_xml
result = await self.query_helper.try_send_str(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\server\ext\rk7_api\async_client\query_helpers.py", line 24, in try_send_str
async with session.post(
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\client.py", line 1423, in __aenter__
self._resp: _RetType = await self._coro
^^^^^^^^^^^^^^^^
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\client.py", line 701, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 544, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1050, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1394, in _create_direct_connection
raise last_exc
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1363, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1120, in _wrap_create_connection
raise ClientConnectorSSLError(req.connection_key, exc) from exc
Cannot connect to host 127.0.0.1:3015 ssl:<ssl.SSLContext object at 0x000001E811FEFED0> [[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)]: aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host 127.0.0.1:3015 ssl:<ssl.SSLContext object at 0x000001E811FEFED0> [[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)]
I think the problem is not with aiohttp
but with the Python ssl
package, but I don't know how to solve the problem. I have tried disabling ssl validation in different ways:
trust_env=True
;ClientSession
create my own ssl_context
that disables ssl checking;SSLContext
with disabled SSL checking instead of ssl=False
to execute the request.I have Python==3.12.3
.
aiohappyeyeballs==2.4.4
aiohttp==3.11.10
aiosignal==1.3.1
attrs==24.2.0
frozenlist==1.5.0
idna==3.10
multidict==6.1.0
propcache==0.2.1
yarl==1.18.3
In my case, the target server was using TLS 1.0, which is no longer supported since python==3.10
. This solution worked for me:
https://stackoverflow.com/a/78645464/28698891
This is something to be very careful with, as it puts your application at risk.
ssl=False
reduces the security level by relaxing cert validation, but it doesn't allow everything. It still has reasonably sane defaults.
In this case it looks like your server may only support SSLv3, which has been deprecated for a decade (and disabled in most clients for longer).
You will need to pass a custom SSLContext
to allow such as a low-level of security.
You could try something like:
ssl_context = ssl.create_default_context()
ssl_context.minimum_version = ssl.TLSVersion.SSLv3
You can see the other options if you need to change ciphers or anything else in the docs: https://docs.python.org/3/library/ssl.html#ssl.SSLContext
Also, it's important to remember that with these settings you are using an insecure connection and should avoid sending any data you wouldn't send over plain HTTP.