Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3 urllib with self-signed certificates

I'm attempting to download some data from an internal server using Python. Since it's internal, it uses a self-signed certificate. (We don't want to pay Verisign for servers that will never appear "in the wild.") The Python 2.6 version of the code worked fine.

response = urllib2.urlopen(URL)
data = csv.reader(response)

I'm now trying to update to Python 3.4 (long story, don't ask.) However, using Python 3's urllib fails:

response = urllib.request.urlopen(URL)

It throws a CERTIFICATE_VERIFY_FAILED error.

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)>

In reading around the web, apparently Python 2.6 urllib2 doesn't bother to verify certificates. Some versions of urllib allow "verify=False" to be passed to the method signature, but that doesn't appear to work in Python 3.4.

Does anyone know how I can get around this? I'd like to avoid using the Requests package because of corporate security guidelines.

like image 257
vaFyreHeart Avatar asked Mar 08 '16 18:03

vaFyreHeart


People also ask

Is Urllib included in Python 3?

The urllib module in Python 3 allows you access websites via your program. This opens up as many doors for your programs as the internet opens up for you. urllib in Python 3 is slightly different than urllib2 in Python 2, but they are mostly the same.

Is Urllib and urllib3 same?

The Python 3 standard library has a new urllib which is a merged/refactored/rewritten version of the older modules. urllib3 is a third-party package (i.e., not in CPython's standard library).

Is Urllib faster than requests?

I found that time took to send the data from the client to the server took same time for both modules (urllib, requests) but the time it took to return data from the server to the client is more then twice faster in urllib compare to request. I'm working on localhost.


2 Answers

Use following for disabling SSL certificate validation for a URL

import ssl
myssl = ssl.create_default_context();
myssl.check_hostname=False
myssl.verify_mode=ssl.CERT_NONE
urlopen("URL",context=myssl)

Use following to disable SSL certificate validations for all URLs

 ssl._create_default_https_context = ssl._create_unverified_context
 urlopen("URL");
like image 58
Sanj Avatar answered Oct 16 '22 09:10

Sanj


urllib.request.urlopen has a context keyword parameter that accepts an SSLContext object. So, passing a SSLContext object with .verify_mode set to ssl.CERT_NONE i.e. SSLContext.verify_mode = ssl.CERT_NONE should be equal to verify=False

like image 39
Muhammad Tahir Avatar answered Oct 16 '22 10:10

Muhammad Tahir