twilio / twilio-python

A Python module for communicating with the Twilio API and generating TwiML.

Home Page:https://www.twilio.com/docs/libraries/python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

REQUESTS_CA_BUNDLE environment variable not respected

matletix opened this issue · comments

Issue Summary

When setting the REQUESTS_CA_BUNDLE environment variable to use a custom CA with the requests module, twilio doesn't pick it up in its http_client.

Context : my company uses SSL proxying, therefore I need to be able to add my company custom CA for SSL verification. When making simple requests via requests.get(), it works well by just setting the REQUESTS_CA_BUNDLE environment variable that is picked up by requests. However, twilio uses the "prepared request flow" of requests here : https://github.com/twilio/twilio-python/blob/main/twilio/http/http_client.py#L90

As specified in the requests documentation :

When you are using the prepared request flow, keep in mind that it does not take into account the environment. This can cause problems if you are using environment variables to change the behaviour of requests. For example: Self-signed SSL certificates specified in REQUESTS_CA_BUNDLE will not be taken into account. As a result an SSL: CERTIFICATE_VERIFY_FAILED is thrown. You can get around this behaviour by explicitly merging the environment settings into your session:

from requests import Request, Session

s = Session()
req = Request('GET', url)

prepped = s.prepare_request(req)

# Merge environment settings into session
settings = s.merge_environment_settings(prepped.url, {}, None, None, None)
resp = s.send(prepped, **settings)

print(resp.status_code)```

Steps to Reproduce

  1. Set the REQUESTS_CA_BUNDLE environment variable to the path to a necessary custom CA certificate
  2. Make a request with requests.get : the requests picks up the CA in REQUESTS_CA_BUNDLE
  3. Make a request with twilio, for example via client.messages.create, the CA in REQUESTS_CA_BUNDLE isn't picked up and a SSL: CERTIFICATE_VERIFY_FAILED exception is raised.

Exception/Log

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lib/python3.8/site-packages/twilio/rest/api/v2010/account/message/__init__.py", line 95, in create
payload = self._version.create(method='POST', uri=self._uri, data=data, )
File "lib/python3.8/site-packages/twilio/base/version.py", line 193, in create
response = self.request(
File "lib/python3.8/site-packages/twilio/base/version.py", line 39, in request
return self.domain.request(
File "lib/python3.8/site-packages/twilio/base/domain.py", line 38, in request
return self.twilio.request(
File "lib/python3.8/site-packages/twilio/rest/__init__.py", line 131, in request
return self.http_client.request(
File "lib/python3.8/site-packages/twilio/http/http_client.py", line 91, in request
response = session.send(
File "lib/python3.8/site-packages/requests/sessions.py", line 645, in send
r = adapter.send(request, **kwargs)
File "lib/python3.8/site-packages/requests/adapters.py", line 517, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.twilio.com', port=443): Max retries exceeded with url: [MASQUED] (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)')))

Technical details:

  • twilio-python version: 7.8.0
  • python version: 3.9

Fixed by #592

Thank you for the PR! We will review it soon.