False SSL certificate subjectAltName warnings for older Python versions.
See original GitHub issueThe change introduced by #497 causes incorrect deprecation warnings to be generated by older Python versions. Specifically, it looks like if using Python 2.7.2 or older, the warning:
SecurityWarning: Certificate has no `subjectAltName`, falling back to check for a `commonName` for now. This feature is being removed by major browsers and deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 for details.)
SecurityWarning
is generated even though the SSL certificate of the target site has the subjectAltName field.
Test script is:
import urllib3
import certifi
http = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED', # Force certificate check.
ca_certs=certifi.where(), # Path to the Certifi bundle.
)
r = http.request('GET', 'https://collector.newrelic.com/')
print r.status, r.data
The underlying reason is that older Python versions are not returning the subjectAltName field even though it exists in the certificate.
# openssl s_client -connect collector.newrelic.com:443 | tee newrelic.cert
…. lots of output deleted
QUIT
# openssl x509 -inform PEM -in newrelic.cert -text
…. lots of output deleted
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:*.newrelic.com, DNS:newrelic.com
…. lots more output delete
# python2.6
Python 2.6.9 (default, Oct 22 2014, 19:47:46)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import _ssl
>>> _ssl._test_decode_cert('newrelic.cert')
{'notBefore': 'Apr 9 00:00:00 2014 GMT', 'serialNumber': '510F0C495E89A1BEEA2AA572D1D4058E', 'notAfter': 'Apr 16 23:59:59 2015 GMT', 'version': 3, 'subject': ((('countryName', u'US'),), (('stateOrProvinceName', u'California'),), (('localityName', u'San Francisco'),), (('organizationName', u'New Relic, Inc.'),), (('commonName', u'*.newrelic.com'),)), 'issuer': ((('countryName', u'US'),), (('organizationName', u'GeoTrust Inc.'),), (('commonName', u'GeoTrust SSL CA - G2'),))}
$ python2.7
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import _ssl
>>> _ssl._test_decode_cert('newrelic.cert')
{'notBefore': 'Apr 9 00:00:00 2014 GMT', 'serialNumber': '510F0C495E89A1BEEA2AA572D1D4058E', 'notAfter': 'Apr 16 23:59:59 2015 GMT', 'version': 3, 'subject': ((('countryName', u'US'),), (('stateOrProvinceName', u'California'),), (('localityName', u'San Francisco'),), (('organizationName', u'New Relic, Inc.'),), (('commonName', u'*.newrelic.com'),)), 'issuer': ((('countryName', u'US'),), (('organizationName', u'GeoTrust Inc.'),), (('commonName', u'GeoTrust SSL CA - G2'),))}
# python2.7
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import _ssl
>>> _ssl._test_decode_cert('newrelic.cert')
{'subjectAltName': (('DNS', '*.newrelic.com'), ('DNS', 'newrelic.com')), 'notBefore': 'Apr 9 00:00:00 2014 GMT', 'serialNumber': '510F0C495E89A1BEEA2AA572D1D4058E', 'notAfter': 'Apr 16 23:59:59 2015 GMT', 'version': 3, 'subject': ((('countryName', u'US'),), (('stateOrProvinceName', u'California'),), (('localityName', u'San Francisco'),), (('organizationName', u'New Relic, Inc.'),), (('commonName', u'*.newrelic.com'),)), 'issuer': ((('countryName', u'US'),), (('organizationName', u'GeoTrust Inc.'),), (('commonName', u'GeoTrust SSL CA - G2'),))}
# python3.3
Python 3.3.6 (default, Oct 12 2014, 13:56:06)
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _ssl
>>> _ssl._test_decode_cert('newrelic.cert')
{'notBefore': 'Apr 9 00:00:00 2014 GMT', 'subjectAltName': (('DNS', '*.newrelic.com'), ('DNS', 'newrelic.com')), 'version': 3, 'issuer': ((('countryName', 'US'),), (('organizationName', 'GeoTrust Inc.'),), (('commonName', 'GeoTrust SSL CA - G2'),)), 'notAfter': 'Apr 16 23:59:59 2015 GMT', 'serialNumber': '510F0C495E89A1BEEA2AA572D1D4058E', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'San Francisco'),), (('organizationName', 'New Relic, Inc.'),), (('commonName', '*.newrelic.com'),))}
This was found by virtue of @kennethreitz requests module bundling latest urllib3 and producing incorrect warnings all the time.
We are having to resort to ignoring the warning:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
r = session.post(url, params=params, headers=headers,
proxies=proxies, timeout=timeout, data=data,
verify=cert_loc)
If confirmed that older Python versions do not provide this information from a certificate, you possibly should change urllib3 to only generate the warning if using Python 2.7.3 or newer.
Issue Analytics
- State:
- Created 9 years ago
- Comments:18 (10 by maintainers)

Top Related StackOverflow Question
We do not use old versions of Python. We are in the same boat as you yourselves are. You have users/customers who you can’t control and who will use old versions of Python with your software because that is the version of Python their operating system supplies, but which have been patched by the OS provider. You therefore do your due diligence and test with a range of Python versions. That is the only reason we have found this.
If you yourselves were testing with older Python versions and testing sufficiently the functionality of your package you might have come across it yourselves. If you are ignoring the reality that your users will use old versions and aren’t testing with then, then you should be advertising your package as incompatible with or entirely untested with older Python versions.
Alright, let’s behave ourselves. It’s nice to respect each others’ time, and we can all strive to make our lives safer and easier within reason. 😃