urllib2 - ability skip certificate verification - python

I need to simulate somehow option -k (vide --insecure to ignore SSL certificate verification) for curl but using urllib2. Any clues?

There is nothing special to do here. urllib2 does not do SSL certificate verification by default. There is a warning in the documentation http://docs.python.org/library/urllib2.html
Warning HTTPS requests do not do any verification of the server’s certificate.

Related

Python: System CA certificates not recognized by urllib3

When I try to access any HTTP website, even one of the most popular, I get a SSL warning from urllib3 module.
>>> import urllib3
>>> http = urllib3.PoolManager()
>>> http.request("GET", "https://www.google.de")
/usr/lib/python2.7/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
<urllib3.response.HTTPResponse object at 0x7f5251466c90>
>>>
Can somebody please help me getting this fixed?
Unfortunately I have to use a API that is apparently using urllib3 under the hood to do the actual REST calls.
So I have to get it fixed w/o avoiding urllib3 module.
I've already checked the ca certificates using ssl.SSLContext.get_ca_certs() which contains the CA certificate.
Doing the same with curl or openssl, works without any verification warnings.
Thanks in advance.
The urllib3 docs explain how to explicitly specify a certificate bundle. You just have to pass the path to your certificates when you initialize PoolManager():
import urllib3
http = urllib3.PoolManager(
cert_reqs="CERT_REQUIRED",
ca_certs="/path/to/your/certificate_bundle"
)
resp = http.request("GET", "https://example.com")
By default it uses the certifi certificate bundle, so you shouldn't even have to do this unless you are using self-signed certificates or a private CA. If you are seeing this problem with popular sites, something is wrong with your CA related environment variables or your certifi bundle, or you are hitting a bug. Upgrade to the latest versions of certifi and urllib3. Some CA related behavior has also changed in recent versions.

Why am I seeing InvalidProxyConfigurationWarning when using an HTTPS proxy with urllib3?

When using a urllib3.ProxyManager() with an HTTPS proxy URL I'm seeing a warning called InvalidProxyConfigurationWarning on version 1.25.9 of urllib3. I didn't get this warning before, what does it mean?
This warning is new in urllib3 v1.25.9 and means that your proxy which is configured to use HTTPS is not doing what you intended.
See this issue for more information: https://github.com/urllib3/urllib3/issues/1850
Copied below is the text from the issue.
urllib3 up to v1.25.x doesn't support HTTPS proxies. When connecting to an HTTPS URL, urllib3 contacts the proxy via HTTP instead of HTTPS even if your proxy URL specifies HTTPS. In urllib3 v1.26.x we're planning on supporting HTTPS proxies properly and are giving an early warning to users to switch their proxy URLs from HTTPS to HTTP to not encounter issues when upgrading later.
import urllib3
# HTTPS proxy, should change!
http = urllib3.ProxyManager("https://1.2.3.4")
http.request("GET", "https://example.com") # Warning would be raised here.
# Switch to this, will maintain current behavior when connecting to HTTPS URLs.
http = urllib3.ProxyManager("http://1.2.3.4")
http.request("GET", "https://example.com") # Warning won't be raised, same behavior as above.
Your proxy may be configured externally like in a HTTPS_PROXY environment variable or via requests.Session(proxy_url=...) or configured by your OS.
(FYI I'm the current lead maintainer of urllib3)

Python Requests with wincertstore

I'm trying to connect to my corporate's internal webpages through the requests package, but since python does not use the windows default trusted certificates the connection is denied. I found out that wincertstore can be used to fetch the windows default certificates. But I'm still not sure how to use that along with the my request. Below is the code I have tried so far.............
import requests, socket, atexit, ssl, wincertstore
from requests.auth import HTTPBasicAuth
certfile = wincertstore.CertFile()
certfile.addstore("CA")
certfile.addstore("ROOT")
atexit.register(certfile.close)
ssl_sock = ssl.wrap_socket(s,ca_certs=certfile.name,
cert_reqs=ssl.CERT_REQUIRED)
requests.get(url)
I get the following error...................
requests.exceptions.SSLError: HTTPSConnectionPool(host='myhost', port=443): Max retries exceeded with url: myurl (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))
I am able to use wget on the same url and download the content.
wget --no check certificate --user=my username --password=my password URL
But I am not interested in downloading the content as I only need to scrape a small portion of the webpage content.
Pythin version = 3.6.5
Wincertstore link - Link
Thanks in advance for your help..............
I had a similar issue and fixed it using the python-certifi-win32 package (now out of maintenance):
As of 2022 (as mentioned by Briareos386 in the comments)
pip install pip-system-certs
Original answer (out of maintenance)
pip install python-certifi-win32
now you can just use:
requests.get(url, verify=True)
and the certificate is checked using the Windows Certificate Store.
Note:
This only works if the certificate is installed in the Windows Certificate Store...
This is all explained in the SSL Cert Verification section of the requests docs.
By default, requests uses the certs from certifi if present, falling back to whatever urllib3 thinks is your OS cert store, which itself falls back on whatever Python thinks it is (although in older versions it often didn't).
Your company apparently has a private, maybe even self-signed, cert, which isn't going to be in certifi. It might be in the Windows cert store—in which case urllib3 should automatically pick it up—but I suspect that it isn't. Maybe the cert is installed directly into some custom browser setup your IT department forces you to use, instead of into the OS store. Or maybe it's not installed at all. (You didn't mention being able to access this site in a browser without seeing a broken-lock icon…)
You're passing --no check certificate (or, more likely, --no-check-certificate?) to wget, so you're just not verifying SSL. And if you want to do the same thing in requests, that's just:
requests.get(url, verify=False)
If you're pretty sure that you do have the cert installed, even though wget can't find it… well, your code isn't going to work as written. Here's what would work:
Ignore the cert and just disable validation, as shown above.
Figure out where the relevant cert actually is installed and how to load it, and:
Pass it as the verify argument on every requests call.
Set it up somewhere statically and pass it in an environment variable.
Install it into your default cert store so everything works automatically.
Write an HTTPAdapter that installs it into your requests session.
First, your code is just trying to get the default cert in exactly the same way Python already does. That wincertstore module is just a backport of what's already builtin to Python 3.4+.
Second, all your code is doing is getting a cert, using it to create an SSL socket, ignoring that socket, and telling requests to do its normal thing. That isn't going to help anything. If you want to pass a cert to requests, you either do this:
requests.get(url, verify='/path/to/cert')
… or put it in the environment variable REQUESTS_CA_BUNDLE
… or do the HTTPAdapter code that I showed you in chat (and which you found an old, non-working version of somewhere unspecified). See HTTPAdapter in the docs if you actually want to do that.
In my case (Windows 10 + Python 3.10.2 + Elasticsearch 8.0.1)
When I ran the code below
requests.get('https://192.168.1.3:9200')
I got this error
Caused by SSLError(SSLCertVerificationError(1, '[SSL:
CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed
certificate in certificate chain (_ssl.c:997)')))
I tried previous solutions but none of them worked for me. I could fix the problem after adding Kibana's CA SSL certificate into Python's default certificate store.
Kibana's CA SSL can be found in your Kibana config file (kibana.yml > elasticsearch.ssl.certificateAuthorities)
Python's default certificate store can be found with this Python code
certifi.where()
Then copy the Kibana's CA certificate content and
paste it into the cacert.pem file.
Then it worked for me.

Python HTTPS server - Certificate validation

I need to create simple https server with Python. I've used this tutorial https://www.piware.de/2011/01/creating-an-https-server-in-python/ and it works with one small "but".
When i try to curl my server (ex. curl -vvv https://domain.com) response looks similar to:
curl: (60) SSL certificate problem: unable to get local issuer
certificate More details here: LINK
Thanks in advance for any help.
Try using your complete certificate chain instead of only your certificate (and your key) on your script:
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='/path/to/fullchain.pem', server_side=True, keyfile='/path/to/server.key')
If you're using a self-signed certificate, cURL won't accept it unless you install it on your local CA certs or run cURL with -k:
curl -vvvk https://domain.com
The certificate chain is just a series of certificates, from your local issued up to the global (including intermediates), CAs usually provide it.

Self-Signed Certificates and Urllib with Python

I have a self-signed certificate file, and I need to make requests to a REST endpoint that requires the certificate. How do I pass this information using the standard python 2.7.x libraries?
Is there a way I can check if the current user has the self-signed certificate installed in the certificate store on Windows? If so, can I grab the certificate?
How do you just use urllib/urllib2 to pass a self-signed certificate?
Thank you

Categories

Resources