Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Requests getting SSLerror

Trying to make a simple get request using Requests session but I keep getting SSLerror for a specific site. I think maybe the problem is with the site (I did a scan using https://www.ssllabs.com, results are down bellow), but I cant be sure because I have no knowledge in this area :) I would sure like to understand what is going on.

A solution/explanation would be great, thanks!

The code:

import requests

requests.get('https://www.reporo.com/')

I'm getting the next error:

SSLError: [Errno bad handshake] [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]

---------------------------------------------------------------------------
SSLError                                  Traceback (most recent call last)
<ipython-input-7-cfc21b287fee> in <module>()
----> 1 requests.get('https://www.reporo.com/')

/usr/local/lib/python2.7/dist-packages/requests/api.pyc in get(url, **kwargs)
     63 
     64     kwargs.setdefault('allow_redirects', True)
---> 65     return request('get', url, **kwargs)
     66 
     67 

/usr/local/lib/python2.7/dist-packages/requests/api.pyc in request(method, url, **kwargs)
     47 
     48     session = sessions.Session()
---> 49     response = session.request(method=method, url=url, **kwargs)
     50     # By explicitly closing the session, we avoid leaving sockets open which
     51     # can trigger a ResourceWarning in some cases, and look like a memory leak

/usr/local/lib/python2.7/dist-packages/requests/sessions.pyc in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    459         }
    460         send_kwargs.update(settings)
--> 461         resp = self.send(prep, **send_kwargs)
    462 
    463         return resp

/usr/local/lib/python2.7/dist-packages/requests/sessions.pyc in send(self, request, **kwargs)
    571 
    572         # Send the request
--> 573         r = adapter.send(request, **kwargs)
    574 
    575         # Total elapsed time of the request (approximately)

/usr/local/lib/python2.7/dist-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
    429         except (_SSLError, _HTTPError) as e:
    430             if isinstance(e, _SSLError):
--> 431                 raise SSLError(e, request=request)
    432             elif isinstance(e, ReadTimeoutError):
    433                 raise ReadTimeout(e, request=request)

SSLError: [Errno bad handshake] [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]

I ran a scan at https://www.ssllabs.com and got the following:

SSL Report: reporo.com
Assessed on:  Sun Feb 22 21:42:57 PST 2015 | Clear cache Scan Another >>

    Server  Domain(s)   Test time   Grade
1   154.51.128.13 
Certificate not valid for domain name 
reporo.com
Sun Feb 22 21:40:53 PST 2015 
Duration: 9.167 sec -
2   198.12.15.168 
protected.ddosdefend.com 
Ready 
www.reporo.com

Sun Feb 22 21:41:02 PST 2015 
Duration: 115.189 sec   
F
like image 382
Captain_Meow_Meow Avatar asked Feb 23 '15 05:02

Captain_Meow_Meow


People also ask

How do I disable the security certificate check in Python requests?

Method 1: Passing verify=False to request methodAlong with the URL also pass the verify=False parameter to the method in order to disable the security checks.

How does Python handle SSL certificates?

Python by default just accepts and uses SSL certificates when using HTTPS, so even if a certificate is invalid, Python libraries such as urllib2 and Twisted will just happily use the certificate.


4 Answers

The certificate itself for www.reporo.com (not reporo.com) is valid, but it is missing a chain certificate as shown in the report by ssllabs:

Chain issues    Incomplete
....
2   Extra download  Thawte DV SSL CA 
Fingerprint: 3ca958f3e7d6837e1c1acf8b0f6a2e6d487d6762 

The "Incomplete" and "Extra download" are the major points. Some browsers will have the missing chain certificate cached, others will do the download and other will fail. If you try the site with a fresh Firefox profile (which does not have any certificates cached) it will fail too.

You could download the missing chain certificates and use it as trusted CA certificate with the verify parameter for requests. Don't just disable validation because then you are open to man-in-the-middle attacks.

Step by step instruction:

  • Download the missing certificate at https://ssl-tools.net/certificates/vqgvhb-thawte-dv-ssl-ca (found by searching for the fingerprint given in the report from SSLLabs). Download the file in PEM format, i.e. https://ssl-tools.net/certificates/3ca958f3e7d6837e1c1acf8b0f6a2e6d487d6762.pem.
  • Download the root certificate at https://ssl-tools.net/certificates/91c6d6ee3e8ac86384e548c299295c756c817b81.pem (also found by searching for fingerprint).
  • Cat both files together into a new file chain.pem. Make sure that each of the files did end with a valid end of line character (which they do not as downloaded). The resulting file should look like this.
  • Modify your call to

    requests.get('https://www.reporo.com/', verify = 'chain.pem')
    
like image 185
Steffen Ullrich Avatar answered Oct 12 '22 03:10

Steffen Ullrich


You can disable certificate verification:

requests.get('https://www.reporo.com/', verify=False)

but without certificate verification there is no man-in-the-middle attack protection.

like image 43
Colin Avatar answered Oct 12 '22 03:10

Colin


I had the same error. Downgrading requests from requests-2.17.3 to requests-2.11.0 solved it for me.

pip uninstall requests
pip install requests==2.11.0
like image 1
Aleksei Denisov Avatar answered Oct 12 '22 03:10

Aleksei Denisov


Ran into similar issue and fixed by following:

pip install -U requests[security]
like image 1
Deqing Avatar answered Oct 12 '22 03:10

Deqing