slackapi / bolt-python

A framework to build Slack apps using Python
https://tools.slack.dev/bolt-python/
MIT License
1.06k stars 245 forks source link

urllib.error.URLError: certificate verify failed on macOS #571

Closed nicwaller closed 2 years ago

nicwaller commented 2 years ago

I tried starting a new project with bolt-python and I ran into an SSL certificate error before adding any of my own code.

Reproducible in:

I get an error immediately after calling this line of code:

app = App(token=os.environ["SLACK_BOT_TOKEN"])

See detailed steps to reproduce below.

The slack_bolt version

nicwaller@serendipity broken % ./venv/bin/pip freeze
slack-bolt==1.11.1
slack-sdk==3.13.0

Python runtime version

nicwaller@serendipity broken % ./venv/bin/python3 --version
Python 3.9.2

OS info

nicwaller@serendipity broken % sw_vers && uname -v
ProductName:    macOS
ProductVersion: 12.1
BuildVersion:   21C52
Darwin Kernel Version 21.2.0: Sun Nov 28 20:29:10 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T8101

Steps to reproduce:

  1. Set up a python3 virtualenv
  2. Install slack-bolt==1.11.1
  3. Ensure SLACK_BOT_TOKEN is populated with a valid bot token
  4. Run the following Python code:
from slack_bolt import App
import os
app = App(token=os.environ["SLACK_BOT_TOKEN"])

Full transcript below:

nicwaller@serendipity broken % python3 -m venv venv

nicwaller@serendipity broken % venv/bin/pip3 install slack-bolt==1.11.1
Collecting slack-bolt==1.11.1
  Using cached slack_bolt-1.11.1-py2.py3-none-any.whl (176 kB)
Collecting slack-sdk<4,>=3.9.0
  Using cached slack_sdk-3.13.0-py2.py3-none-any.whl (260 kB)
Installing collected packages: slack-sdk, slack-bolt
Successfully installed slack-bolt-1.11.1 slack-sdk-3.13.0

nicwaller@serendipity broken % export SLACK_BOT_TOKEN=[REDACTED]
nicwaller@serendipity broken % ./venv/bin/python3
Python 3.9.2 (v3.9.2:1a79785e3e, Feb 19 2021, 09:08:59)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from slack_bolt import App
>>> import os
>>> app = App(token=os.environ["SLACK_BOT_TOKEN"])
Failed to send a request to Slack API server: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>
Failed to send a request to Slack API server: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 1346, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1255, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1301, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1250, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1010, in _send_output
    self.send(msg)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 950, in send
    self.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1424, in connect
    self.sock = self._context.wrap_socket(self.sock,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_bolt/app/app.py", line 338, in __init__
    self._init_middleware_list(
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_bolt/app/app.py", line 370, in _init_middleware_list
    auth_test_result = self._client.auth_test(token=self._token)
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/client.py", line 1512, in auth_test
    return self.api_call("auth.test", params=kwargs)
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 145, in api_call
    return self._sync_send(api_url=api_url, req_args=req_args)
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 182, in _sync_send
    return self._urllib_api_call(
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 297, in _urllib_api_call
    response = self._perform_urllib_http_request(url=url, args=request_args)
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 504, in _perform_urllib_http_request
    raise err
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 412, in _perform_urllib_http_request
    resp = self._perform_urllib_http_request_internal(url, req)
  File "/Users/nicwaller/workspace/crowd/broken/venv/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 537, in _perform_urllib_http_request_internal
    resp = urlopen(  # skipcq: BAN-B310
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 517, in open
    response = self._open(req, data)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 534, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 1389, in https_open
    return self.do_open(http.client.HTTPSConnection, req,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 1349, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>

Expected result:

Actually, I wouldn't expect anything to happen until I run app.start(). So it's pretty surprising to me that it's failing here.

But also, I would expect to see a line like this:

python3[26175]: ⚡️ Bolt app is running! (development server)

Actual result:

I get an exception traceback (as detailed above)

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

nicwaller commented 2 years ago

This seems isolated to macOS. I was unable to reproduce the issue from an Ubuntu 20.04 virtual machine.

nicwaller commented 2 years ago

I tried re-installing Python and noticed this warning in the installer which is probably related:

Certificate verification and OpenSSL

This package includes its own private copy of OpenSSL 1.1.1. The trust certificates in system and user keychains managed by the Keychain Access application and the security command line utility are not used as defaults by the Python ssl module. A sample command script is included in /Applications/Python 3.9 to install a curated bundle of default root certificates from the third-party certifi package (https://pypi.org/project/certifi/). Double-click on Install Certificates to run it.

The bundled pip has its own default certificate store for verifying download connections.

image
nicwaller commented 2 years ago

✅ bolt-python is working for me now after I ran /Applications/Python\ 3.10/Install Certificates.command.

My install was originally missing the /Applications/Python\ 3.10 directory because I had not chosen to install GUI tools when running the Python installer. After re-installing with GUI tools, I was able to run Install Certificates.command.

smbock42 commented 2 years ago

Hello, I am having the same issue that you had — I already installed certifi and ran the Python certificate install. Do you have any other suggestions? Thanks!