Pages

Saturday, February 1, 2020

Fixing [SSL: CERTIFICATE_VERIFY_FAILED]

Scenario:
You are developing a Python app that needs to perform OAuth and talking to Google APIs. And you also want to intercept HTTP traffic to gain more understanding or debug your app, but faced the following terrible terrible messages:

Traceback (most recent call last):
  File "alt_google_sample.py", line 17, in <module>
    creds = tools.run_flow(flow, store, http=my_http)
  File "C:\python38\lib\site-packages\oauth2client\_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "C:\python38\lib\site-packages\oauth2client\tools.py", line 243, in run_flow
    credential = flow.step2_exchange(code, http=http)
  File "C:\python38\lib\site-packages\oauth2client\_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "C:\python38\lib\site-packages\oauth2client\client.py", line 2053, in step2_exchange
    resp, content = transport.request(
  File "C:\python38\lib\site-packages\oauth2client\transport.py", line 280, in request
    return http_callable(uri, method=method, body=body, headers=headers,
  File "C:\python38\lib\site-packages\httplib2\__init__.py", line 1982, in request
    (response, content) = self._request(
  File "C:\python38\lib\site-packages\httplib2\__init__.py", line 1650, in _request
    (response, content) = self._conn_request(
  File "C:\python38\lib\site-packages\httplib2\__init__.py", line 1557, in _conn_request
    conn.connect()
  File "C:\python38\lib\site-packages\httplib2\__init__.py", line 1326, in connect
    self.sock = self._context.wrap_socket(sock, server_hostname=self.host)
  File "C:\python38\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\python38\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\python38\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1108)

>:(

What's the issue?
If you're doing man-in-the-middle (MITM) for HTTP requests/responses, your TLS/SSL verification will certainly fail. Unfortunately, 'verify=False' does not work as the Google API client library uses httplib2 instead. However, all is not lost.

Remediation:
Import httplib2, instantiate a Http() object and use 'disable_ssl_certificate_validation=True' as the argument.

If you are using the Google Tutorial's sample code, this won't exactly work. :(


Solution #1: Disable the SSL verification altogether during testing.
...
my_http = httplib2.Http(disable_ssl_certificate_validation=True)

SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
store = file.Storage('token.json')
creds = store.get()

if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('credentials.json'SCOPES)
    creds = tools.run_flow(flow, store, http=my_http)
    service = build('calendar''v3', http=creds.authorize(my_http))
...

Solution #2: Use self-signed certificate
Extract your intercepting software (e.g. Burpsuite) certificate, convert it to PEM format and then use the following code:
...
my_http = httplib2.Http(ca_certs='./burp.pem')

SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
store = file.Storage('token.json')
creds = store.get()

if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('credentials.json'SCOPES)
    creds = tools.run_flow(flow, store, http=my_http)
    service = build('calendar''v3', http=creds.authorize(my_http))
...

For full code, please visit:
https://github.com/breaktoprotect/Useful-Code-Snippets/blob/master/googleapiclient_disable_ssl_verify.py

Screenshots of results - Yay - interception successful!

No comments:

Post a Comment