Summary
The pusher package currently ships with three dependencies that exist solely for Python 2 SNI (Server Name Indication) support: pyopenssl, pyasn1, and ndg-httpsclient. These dependencies have known security vulnerabilities:
Why these dependencies exist
These were added for Python 2, which lacked native SNI support in its ssl module. The workaround was:
pyopenssl — provided SNI-capable SSL via OpenSSL bindings
ndg-httpsclient — patched urllib3 to use pyopenssl
pyasn1 — ASN.1 parsing required by both pyopenssl and ndg-httpsclient
In the codebase, this is visible in pusher/requests.py, where the pyopenssl injection is gated behind sys.version_info < (3,) — meaning it was never executed on Python 3.
Why we can't just upgrade to fixed versions
Simply pinning to the fixed versions (pyopenssl>=26.0.0, pyasn1>=0.6.3) would not restore Python 2 support because:
pyopenssl dropped Python 2 support years ago (around v22.0)
pyasn1 also no longer supports Python 2
ndg-httpsclient is unmaintained
So there is no version combination that fixes these CVEs while maintaining Python 2 compatibility.
Why removing Python 2 support is the right approach
- Python 2 reached end-of-life on January 1, 2020 — over 6 years ago
- The project's CI already targets Python 3.10–3.12 only
- The Python 2 code paths (e.g., pyopenssl injection) are dead code on Python 3
- These dependencies add unnecessary attack surface for zero functional benefit on Python 3, as Python 3's stdlib
ssl module handles SNI natively
Changes
- Remove
pyopenssl, ndg-httpsclient, and pyasn1 from install_requires in setup.py
- Remove the dead Python 2 pyopenssl injection code in
pusher/requests.py
- Update
setup.py classifiers and README.md to reflect Python 3 only support
Related PR
Summary
The
pusherpackage currently ships with three dependencies that exist solely for Python 2 SNI (Server Name Indication) support:pyopenssl,pyasn1, andndg-httpsclient. These dependencies have known security vulnerabilities:Why these dependencies exist
These were added for Python 2, which lacked native SNI support in its
sslmodule. The workaround was:pyopenssl— provided SNI-capable SSL via OpenSSL bindingsndg-httpsclient— patchedurllib3to use pyopensslpyasn1— ASN.1 parsing required by both pyopenssl and ndg-httpsclientIn the codebase, this is visible in
pusher/requests.py, where the pyopenssl injection is gated behindsys.version_info < (3,)— meaning it was never executed on Python 3.Why we can't just upgrade to fixed versions
Simply pinning to the fixed versions (
pyopenssl>=26.0.0,pyasn1>=0.6.3) would not restore Python 2 support because:pyopenssldropped Python 2 support years ago (around v22.0)pyasn1also no longer supports Python 2ndg-httpsclientis unmaintainedSo there is no version combination that fixes these CVEs while maintaining Python 2 compatibility.
Why removing Python 2 support is the right approach
sslmodule handles SNI nativelyChanges
pyopenssl,ndg-httpsclient, andpyasn1frominstall_requiresinsetup.pypusher/requests.pysetup.pyclassifiers andREADME.mdto reflect Python 3 only supportRelated PR