-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aiohttp ignoring SSL_CERT_DIR and or SSL_CERT_FILE environment vars. Results in [SSL: CERTIFICATE_VERIFY_FAILED] #3180
Comments
There's this PR #2735 hanging since February. Do you mind picking it up? It'd allow you to have a custom ssl.SSLContext, where you could configure trust as you wish. |
Hi @webknjaz Is 2735 related to aiohttp not using The PR does not read this way, i may *easily be mistaken |
Looks like @webknjaz misread the mentioned PR. aiohttp has no specific code for SSL certificates loading. Please read the standard documentation to figure out how to create |
I dont think its as simple as that - there is a catch 22 here.
To explain further aiohttp does use the system key store, via SSL. We're left where an application can make no obvious use of requests and aiohttp and a companies own root_ca certificate. |
aiohttp follows Python decisions which use system store. If you want requests-like configuration by default -- you can assemble a thin wrapper on top of aiohttp to do it. Personally I dont like this approach |
OK - thanks for the response. |
@asvetlov AFAIR aiohttp does not have any hooks where the end-user could supply their own SSLContext objects and that PR adds one. Am I right? |
system certs are a mess. an unmanageable real mess if we're honest once scratch the surface of it. OSX and Windows you have half a chance, even then its problematic as certs are lazy loaded via s-channel so may or may not be there. Linux is beyond a lost cause - system certs can be in any 1 of 10 locations reported, finding one those isn't enough to assume its "THE" one. Pip tries to use system certs, but falls back to mozillas certifi bundle because system certs are anything anywhere None of that is criticism of aiohttp or python. There is no portability in it without - code on one os is not going to behave the same on another on a lift and shift. |
Google couldn't make using system certs work on linux for Chrome, the average python scripter - myself in this bracket - has no hope. |
@creslinux recently I've been trying to automate (with ansible) adding a coprorate certificate to my laptop and found out that neither Chrome nor Firefox can read system folder, only user's one: turns out that underlying nsslib only promises to read /etc, but in fact does not do that. |
it all seems a bit religious. |
Help yourself. |
What about SSLContext? Only monkey-patching? |
Its a great answer when building on aiohttp directly.
When youre using a library thats is itself using aiohttp is not that simple
The only thing thats true here is I'm not the first or the last to hit
this.
Users will carry the pain again and again and again
The longer its around the deeper and more abstract aiohttp will often get
buried under under other libraries.
Asking users to then fork layers within apps to maintain something that
works for them - "them" being maybe 50% users as python is split on certs -
isnt really an answer that will stand the test of time.
…On 9 August 2018 at 15:20, Sviatoslav Sydorenko ***@***.***> wrote:
What about SSLContext? Only monkey-patching?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3180 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AhCkw5slrWkTrrfGpwi0aSsVkRN_zihQks5uPFNPgaJpZM4VznQt>
.
|
@webknjaz |
Okay, that's what I was asking about :) |
@creslinux your arguments are applicable to any TSL connection, not only HTTP. Would you try to convince python core devs to ship Python with custom root certs? |
I'm not sure what you mean by python.
Aiohttp is my only experience a popular large library for http/s that does
not support the vars.
Requests, pip, twisted, ssl, pycurl all use them.
Outside of python, curl, wget, openssl, and the linux OS use them.
Fairly well the defacto TLS in linux is openssl, so why when openssl is
pointing to the right root CA to be used via ENV vars aiohttp would ignore
that I don't know
Redhat as example.
https://access.redhat.com/articles/2039753
…On Thu, Aug 9, 2018, 9:49 PM Andrew Svetlov ***@***.***> wrote:
@creslinux <https://github.com/creslinux> your arguments are applicable
to any TSL connection, not only HTTP.
I have a feeling that the problem should be fixed on OS or Python level.
Would you try to convince python core devs to ship Python with custom root
certs?
I recall @tiran <https://github.com/tiran> had objections for this
approach.
Honestly, I don't remember the whole pros/cons list.
The security is very sensitive matter, I don't want to make the decision
fast.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3180 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AhCkw2RMYH9DFIiAzaGlKj6c6fap7GZ7ks5uPIRFgaJpZM4VznQt>
.
|
@creslinux while there are various projects supporting such feature, it's out of the scope of aiohttp to do so. Moreover, as @asvetlov outlined, there's a security risk related to this feature. Given that aiohttp is and underlying building block for apps it would be unwise to have a library-specific env var for hijacking root CA. I can imagine that user having two apps in the same env wanting to add a trusted CA to one of them would unintentionally (probably lacking some knowledge) influence the other one as well, creating an extra "invisible" security hole. Also, we would like to avoid creation of the false sense of protection among users. On the other hand, most of the software built on top of aiohttp will probably want their own env vars (unique names etc.), which would we non-conflicting and won't abuse global settings. Based on the above I strongly encourage you to implement this on the level of your app. |
its not risk when the OS its build on uses them.... Its true requests, twisted, aiohttp, ssl - are pillars that many apps are built upon. Linux has no trusted key-store, its misnomer to point out it should be used. |
So in summary
|
The thing is the Python SSL module does support the Env Vars - aiohttp simply ignores SSLs when its using them. Thats the part i dont understand - why use SSL if going to ignore that its instructing to do. |
Correct me if I'm wrong, but aiohttp uses SSL Context and does not directly handle |
python SSL sees the path to be used. It is deciding which parts of the OS to honour and is unusual in this as other apps behave as the OS would intend. SSL_CERT_DIR = /tmp
export SSL_CERT_DIR import ssl
print("\n ssl Paths", ssl.get_default_verify_paths() ,"\n") returns:
|
https://docs.python.org/3/library/ssl.html#libressl-support "SSLContext.set_default_verify_paths() ignores the env vars SSL_CERT_FILE and SSL_CERT_PATH although get_default_verify_paths() still reports them." I think it makes sense to pass the cert from get_default_verify_paths to your ssl context. If you think aiohttp should handle this, make a pull request with your changes for review. Edit: |
@MyNameIsCosmo true @creslinux (1) it depends on the SSL implementation (particularly, python doc emphasizes that LibreSSL ignores env vars) and (2) methods used from there (see more docs). |
@creslinux as for your "wrong" accusations, it's not about being "right" or "incorrect". It's a design decision and keeping the responsibility for breaches on the user's side. |
Thats a very tight cut and past - the full section reads
Thats a different argument libressl not supporting the full spec and not passing a path back so cant used is hardly a great argument for when it is passed back by the default build Python certificate handling explicitly states openssl_capath_env and openssl_cafile_env are used by openssl. Thats 90% linux distributions right there. |
aiohttp is undermining how an OS, openssl, python ssl, and other popular pillars of python libraries manage company CAs. There's no getting away from that. To ignore where the OS says to take certs from and claim its for security when only encourages people to disable verification doesn't really add up. As a simple observation, guys n gals in deployment, users deploying etc - really are not in the main going to re-code and and pick apart an application that ignores their OS, they're just going to disable verification. |
As a final comment, what this policy means in Linux is:
In windows and OSX user have their own keychains/ceritficate stores. |
The env vars SSL_CERT_FILE and SSL_CERT_PATH are handled by OpenSSL, not by Python. They override the location of the default CA cert file and CA cert directory for https://docs.python.org/3/library/ssl.html#ssl.SSLContext.set_default_verify_paths . aiohttp has to use
|
If the var its not passed it wont be used. Same as any var The major distributions are on OpenSSL by default. So unless an admin has explicitly moved away from default SSL this seems pretty moot. Debian by inference is Ubuntu/Mint etc.
True for all the paths returned by OpenSSL, including the host certificate store -- if a user is lucky enough their sys admin root user can be bothered to add a certificate, or accepts 1 users company CA should be added globally for ALL users on the host. That would be a questionable security decision to force unto a multi user host. Mr Foo from Company Foo MUST trust Company Bar's root CA as user Mrs Bar wants to trust her company Bar's CA? -- ???
The var must be set to be read? well...
The var must be set to be read? we.... And the flip side it
Im sorry. This simple encourages to not verify servers. Its counter productive in the extreme. To take the stance you should either install a root CA for 1 user globally, must be root user, or must recode the application. Im shocked - truly SHOCKED Google did not go down this path with Chrome on Linux |
aiohttp calls |
|
Sorry, was my typo. |
exporting
similar for the verify |
Yes, |
Cool! Thank you! |
The link is good, aiohttp does not behave as it describes, it failing to verify servers when a hashed cert is in capath. Can this be raised as a bug then? The from the link provided by @tiran Tested below. Test script:
Run test script with no cert in SSL_CERT_DIR or in store (fails as expected)
set up SSL_CERT_DIR and add a hashed certificate
set, export,
Run test script again - still fails <<---- This is where its broken. We've show SSL module sees capath and there is a hashed certificate in here.
Add to OS store
Now works.
|
@creslinux could you try your snippet with explicitly crafted |
I could but that would be another test / different thing The issue/bug im chasing down is aiohttp is not following OS/openssl/python-ssl guidence. Every link being pointed at by others explicitly states The challenge is users of apps / apps being deployed into environments where "their" company ca certificate is in a location deployed for general use. |
(plus my 6mnth puppy is telling me its her toilet/walk time -- and ... well, carpet priorities) |
@tiran wrote
As tests show |
Reminder: asyncio uses @creslinux I have no certificates to test myself, I need your help to pin down the problem. |
@asvetlov JFYI I'm trying to track SSL testing helpers here: cherrypy/cheroot#95. Maybe we could try to add |
@asvetlov So how do you ignore the ssl certificate error? Is there a parameter like requests verify=False? |
RTFM please: http://docs.aiohttp.org/en/stable/client_advanced.html#ssl-control-for-tcp-sockets |
@asvetlov |
Perhaps you use an old aiohttp version |
@asvetlov thank you very much |
Long story short
The CA file is working with cURL, Python Requests, but not aiohttp, when using
SSL_CERT_DIR
and orSSL_CERT_FILE
environment variables.Our environment uses its own CA root used to decode/encode HTTPS API requests/responses to provide a short lived cache to prevent excessing external requests.
The environment has the following set:
The ca.pem can be successfully used by cURL - with both a positive and negative test shown:
A simple python requests script
req.py
also works as expected, positive and negative testsUsing aysnc/aiohttp
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)
is returned always.The environment settings pointing to the
ca.pem
shown to work for both cURL and requests are seemingly ignoredI have the test script
a.py
asWhich will always produce the failure - output in full:
Expected behaviour
aiohttp does not reject server certificate.
Actual behaviour
SSL verification error
Steps to reproduce
use own CA root certificate to trust HTTPS server.
Your environment
Ubuntu 18.04
Python 3.6.5
ssl version OpenSSL 1.1.0g 2 Nov 2017
Name: aiohttp Version: 3.3.2
Name: requests Version: 2.19.1
Name: certifi Version: 2018.4.16
The text was updated successfully, but these errors were encountered: