44

I have a server setup for testing, with a self-signed certificate, and want to be able to test towards it.

How do you ignore SSL verification in the Python 3 version of urlopen?

All information I found regarding this is regarding urllib2 or Python 2 in general.

urllib in python 3 has changed from urllib2:

Python 2, urllib2: urllib2.urlopen(url[, data[, timeout[, cafile[, capath[, cadefault[, context]]]]])

https://docs.python.org/2/library/urllib2.html#urllib2.urlopen

Python 3: urllib.request.urlopen(url[, data][, timeout]) https://docs.python.org/3.0/library/urllib.request.html?highlight=urllib#urllib.request.urlopen

So I know this can be done in Python 2 in the following way. However Python 3 urlopen is missing the context parameter.

import urllib2
import ssl

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

urllib2.urlopen("https://your-test-server.local", context=ctx)

And yes I know this is a bad idea. This is only meant for testing on a private server.

I could not find how this is supposed to be done in the Python 3 documentation, or in any other question. Even the ones explicitly mentioning Python 3, still had a solution for urllib2/Python 2.

Joakim
  • 11,468
  • 9
  • 44
  • 50
  • Possible duplicate of [How do I disable the ssl check in python 3.x?](https://stackoverflow.com/questions/33770129/how-do-i-disable-the-ssl-check-in-python-3-x) – nngeek Oct 11 '19 at 08:45

3 Answers3

61

The accepted answer just gave advise to use python 3.5+, instead of direct answer. It causes confusion.

For someone looking for a direct answer, here it is:

import ssl
import urllib.request

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

with urllib.request.urlopen(url_string, context=ctx) as f:
    f.read(300)

Alternatively, if you use requests library, it has much better API:

import requests

with open(file_name, 'wb') as f:
    resp = requests.get(url_string, verify=False)
    f.write(resp.content)

The answer is copied from this post (thanks @falsetru): How do I disable the ssl check in python 3.x?

These two questions should be merged.

nngeek
  • 1,912
  • 16
  • 24
  • 1
    I came across this answer after setting `verify=False` (using `requests` library) and realized that I was now getting a lot of warnings from `urllib3` which made it hard to read some of my logs during development. If anyone has this issue, see [this part of the urllib3 documentation](https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings) – RemedialBear Jan 06 '22 at 22:22
6

Python 3.0 to 3.3 does not have context parameter, It was added in Python 3.4. So, you can update your Python version to 3.5 to use context.

Muhammad Tahir
  • 5,006
  • 1
  • 19
  • 36
  • 21
    You can just change default context: `ssl._create_default_https_context = ssl._create_unverified_context` and you don't need ctx at all. – AstraSerg Feb 18 '19 at 14:43
  • 3
    Thanks @AstraSerg, I think your comment would deserve to be converted to a separate answer. – piit79 Aug 15 '19 at 08:45
0

You can specify cert_reqs='CERT_NONE' while creating PoolManager or ProxyManager objects.

For example:

proxy = urllib3.ProxyManager("https://localhost:8443", cert_reqs='CERT_NONE')

or

pool = urllib3.PoolManager(cert_reqs='CERT_NONE')