VYPR
Moderate severityNVD Advisory· Published Jan 18, 2014· Updated Apr 29, 2026

CVE-2013-2037

CVE-2013-2037

Description

httplib2 0.7.2, 0.8, and earlier, after an initial connection is made, does not verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate, which allows man-in-the-middle attackers to spoof SSL servers via an arbitrary valid certificate.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
httplib2PyPI
< 0.10.10.10.1

Affected products

6
  • cpe:2.3:a:httplib2_project:httplib2:*:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:a:httplib2_project:httplib2:*:*:*:*:*:*:*:*range: <=0.7.2
    • cpe:2.3:a:httplib2_project:httplib2:0.8:*:*:*:*:*:*:*
  • cpe:2.3:o:canonical:ubuntu_linux:10.04:*:*:*:lts:*:*:*+ 3 more
    • cpe:2.3:o:canonical:ubuntu_linux:10.04:*:*:*:lts:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:lts:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:12.10:*:*:*:*:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:13.04:*:*:*:*:*:*:*

Patches

1
40cbdcc8586f

ssl: hostname mismatch was checked only once (python2 fix)

https://github.com/httplib2/httplib2Sergey ShepelevJan 4, 2017via ghsa
2 files changed · +40 19
  • python2/httplib2/__init__.py+5 3 modified
    @@ -65,9 +65,12 @@
             socks = None
     
     # Build the appropriate socket wrapper for ssl
    +ssl_SSLError = None
    +ssl_CertificateError = None
     try:
         import ssl # python 2.6
         ssl_SSLError = ssl.SSLError
    +    ssl_CertificateError = ssl.CertificateError
         def _ssl_wrap_socket(sock, key_file, cert_file, disable_validation,
                              ca_certs, ssl_version, hostname):
             if disable_validation:
    @@ -91,7 +94,6 @@ def _ssl_wrap_socket(sock, key_file, cert_file, disable_validation,
                                        cert_reqs=cert_reqs, ca_certs=ca_certs,
                                        ssl_version=ssl_version)
     except (AttributeError, ImportError):
    -    ssl_SSLError = None
         def _ssl_wrap_socket(sock, key_file, cert_file, disable_validation,
                              ca_certs, ssl_version, hostname):
             if not disable_validation:
    @@ -1066,7 +1068,7 @@ def connect(self):
                             raise CertificateHostnameMismatch(
                                 'Server presented certificate that does not match '
                                 'host %s: %s' % (hostname, cert), hostname, cert)
    -            except ssl_SSLError, e:
    +            except (ssl_SSLError, ssl_CertificateError, CertificateHostnameMismatch), e:
                     if sock:
                         sock.close()
                     if self.sock:
    @@ -1076,7 +1078,7 @@ def connect(self):
                     # to get at more detailed error information, in particular
                     # whether the error is due to certificate validation or
                     # something else (such as SSL protocol mismatch).
    -                if e.errno == ssl.SSL_ERROR_SSL:
    +                if getattr(e, 'errno', None) == ssl.SSL_ERROR_SSL:
                         raise SSLHandshakeError(e)
                     else:
                         raise
    
  • python2/httplib2/test/test_ssl_context.py+35 16 modified
    @@ -1,16 +1,18 @@
    -#!/usr/bin/python2
    +#!/usr/bin/env python2
     import BaseHTTPServer
     import logging
     import os.path
    -import unittest
    +import ssl
     import sys
    +import unittest
     
     import httplib2
    -
     from httplib2.test import miniserver
     
    +
     logger = logging.getLogger(__name__)
     
    +
     class KeepAliveHandler(BaseHTTPServer.BaseHTTPRequestHandler):
         """
         Request handler that keeps the HTTP connection open, so that the test can
    @@ -28,27 +30,23 @@ def log_message(self, s, *args):
             # output via logging so nose can catch it
             logger.info(s, *args)
     
    +
     class HttpsContextTest(unittest.TestCase):
         def setUp(self):
             if sys.version_info < (2, 7, 9):
    -            return
    +            if hasattr(self, "skipTest"):
    +                self.skipTest("SSLContext requires Python 2.7.9")
    +            else:
    +                return
     
    -        self.httpd, self.port = miniserver.start_server(
    -            KeepAliveHandler, True)
    +        self.ca_certs_path = os.path.join(os.path.dirname(__file__), 'server.pem')
    +        self.httpd, self.port = miniserver.start_server(KeepAliveHandler, True)
     
         def tearDown(self):
             self.httpd.shutdown()
     
         def testHttpsContext(self):
    -        if sys.version_info < (2, 7, 9):
    -            if hasattr(unittest, "skipTest"):
    -                self.skipTest("SSLContext requires Python 2.7.9")# Python 2.7.0
    -            else:
    -                return
    -        import ssl
    -
    -        client = httplib2.Http(
    -            ca_certs=os.path.join(os.path.dirname(__file__), 'server.pem'))
    +        client = httplib2.Http(ca_certs=self.ca_certs_path)
     
             # Establish connection to local server
             client.request('https://localhost:%d/' % (self.port))
    @@ -61,6 +59,27 @@ def testHttpsContext(self):
             self.assertIsInstance(conn.sock.context, ssl.SSLContext)
             self.assertTrue(conn.sock.context.check_hostname)
             self.assertEqual(conn.sock.server_hostname, 'localhost')
    -        self.assertEqual(conn.sock.context.check_hostname, True)
             self.assertEqual(conn.sock.context.verify_mode, ssl.CERT_REQUIRED)
             self.assertEqual(conn.sock.context.protocol, ssl.PROTOCOL_SSLv23)
    +
    +    def test_ssl_hostname_mismatch_repeat(self):
    +        # https://github.com/httplib2/httplib2/issues/5
    +
    +        # FIXME(temoto): as of 2017-01-05 this is only a reference code, not useful test.
    +        # Because it doesn't provoke described error on my machine.
    +        # Instead `SSLContext.wrap_socket` raises `ssl.CertificateError`
    +        # which was also added to original patch.
    +
    +        # url host is intentionally different, we provoke ssl hostname mismatch error
    +        url = 'https://127.0.0.1:%d/' % (self.port,)
    +        http = httplib2.Http(ca_certs=self.ca_certs_path, proxy_info=None)
    +
    +        def once():
    +            try:
    +                http.request(url)
    +                assert False, 'expected certificate hostname mismatch error'
    +            except Exception as e:
    +                print('%s errno=%s' % (repr(e), getattr(e, 'errno', None)))
    +
    +        once()
    +        once()
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

12

News mentions

0

No linked articles in our index yet.