Open nunoseita opened 1 year ago
Because the underlaying Python module requests does not support client certificates which are protected by password (https://requests.readthedocs.io/en/latest/user/advanced/#client-side-certificates) until now this feature was considered not very useful.
Maybe the feature could have the warning: The private key to your local certificate must be unencrypted. This is a security flaw if the key itself is not in a encrypted filesystem or access to it is not controlled.
And if the key is compromised we can allways revoke and issue a new cert for that client.
Can you consider to make this feature?
@nunoseita do you have the resources to create a prove of work for this? I cannot test this due to missing setup.
@HenriWahl since version 3.3, the SSLContext.load_cert_chain function has an optional argument password to decrypt the key. If the key is not encrypted, the argument is simply ignored: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_cert_chain
So the client certificate authentication could be implemented in a secure way.
@spacefreak86 do you know how to integrate this into the used requests module?
@HenriWahl what do you mean with the used requests module? As far as I can see, you are using urrlib3.request or am I wrong?
@spacefreak86 Nagstamon uses https://requests.readthedocs.io in https://github.com/HenriWahl/Nagstamon/blob/master/Nagstamon/Servers/Generic.py#L32.
The requests module itself is able to handle client certificates: https://docs.python-requests.org/en/latest/user/advanced/#client-side-certificates
Unfortunately, it does not support using encrypted keys. In my opinion, private keys should never be stored unencrypted, so I suggest to use https://github.com/m-click/requests_pkcs12 . In addition to the better security, this is convenient for the users as well, as client certificates are usually stored in PKCS12 format.
What do you think about it?
@spacefreak86 this looks interesting. Would you be able to try an implementation?
Hello!
I've tried using BeautifulSoup to simulate a browser in the terminal...
from bs4 import BeautifulSoup
from requests import Session
from requests_pkcs12 import Pkcs12Adapter
from supersecrets import check_mk_url, dashboard_url, data, headers, password
# Create a session object and add the pkcs12 adapter for client authentication
with Session() as s:
s.mount(check_mk_url, Pkcs12Adapter(pkcs12_filename='certificate.pfx', pkcs12_password=password))
# Send the request with the headers and data
response = s.post(check_mk_url + 'login.py', headers=headers, data=data)
#Check if the login was successful by looking for the auth_global cookie
if 'auth_global' in s.cookies:
# If the login was successful, send a GET request to the dashboard URL
dashboard_response = s.get(dashboard_url)
soup = BeautifulSoup(dashboard_response.content, 'html.parser')
print(soup)
The supersecrets is just a .py file with sensitive data.
What is needed by @nunoseita and me, is just a way to specify the client certificate (the "certificate.pfx" file) and respective password. Without this certificate, it is impossible for Nagstamon to access the website.
Cheers!
Any comments regarding this @HenriWahl @spacefreak86 ?
@NotoriusNeo sorry I did not yet find the time to look at it.
Thank you @alexharrington. @HenriWahl can you check alex work - is it a viable option to have client side certificate? Security is a concearn that is growing and growing - i trully believe, besides my need, that this feature will increase the number of users for nagstamon.
First of all, thank you for an awsome product.
We use a CheckMK server that forces the use of client side certificate and only then we are presented with login prompt. Is that feature possible to be implemented?