VYPR
Medium severity5.9NVD Advisory· Published Nov 4, 2012· Updated Apr 29, 2026

CVE-2012-3446

CVE-2012-3446

Description

Apache Libcloud before 0.11.1 uses an incorrect regular expression during verification of whether 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 a crafted certificate.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
apache-libcloudPyPI
< 0.11.10.11.1

Affected products

1
  • cpe:2.3:a:apache:libcloud:*:*:*:*:*:*:*:*
    Range: <0.11.0

Patches

1
f2af5502dae3

Fix hostname validation in the SSL verification code (CVE-2012-3446). Reported by researchers

https://github.com/apache/libcloudTomaž MurausAug 2, 2012via ghsa
4 files changed · +48 11
  • CHANGES+12 3 modified
    @@ -1,5 +1,14 @@
                                        -*- coding: utf-8 -*-
     
    +Changes with Apache Libcloud 0.11.1:
    +
    +  *) General
    +
    +    - Fix hostname validation in the SSL verification code (CVE-2012-3446).
    +
    +      Reported by researchers from the University of Texas at Austin (Martin
    +      Georgiev, Suman Jana and Vitaly Shmatikov).
    +
     Changes with Apache Libcloud 0.11.0:
     
       *) Compute
    @@ -139,7 +148,7 @@ Changes with Apache Libcloud 0.11.0:
           CloudFiles driver.
           [Tomaz Muraus]
     
    -    - Fix a bug with content_type and and encoding of object and path names in 
    +    - Fix a bug with content_type and and encoding of object and path names in
           the Atmos driver.
           [Russell Keith-Magee]
     
    @@ -234,7 +243,7 @@ Changes with Apache Libcloud 0.10.1:
     
         - Add ex_rescue and ex_unrescue method to OpenStack 1.1 driver. ;
           LIBCLOUD-193
    -      [Shawn Smith] 
    +      [Shawn Smith]
     
         - Include 'password' in the node extra dictionary when calling deploy_node
           if the password auth is used.
    @@ -419,7 +428,7 @@ Changes with Apache Libcloud 0.8.0:
          - Enable ex_delete_image method in the OpenStack 1.1 driver.
            [Shawn Smith]
     
    -     - Return NodeImage instance in OpenStack 1.1 driver ex_save_image method 
    +     - Return NodeImage instance in OpenStack 1.1 driver ex_save_image method
            ; LIBCLOUD-138
            [Shawn Smith]
     
    
  • libcloud/httplib_ssl.py+2 7 modified
    @@ -122,13 +122,8 @@ def _verify_hostname(self, hostname, cert):
             # replace * with alphanumeric and dash
             # replace . with literal .
             valid_patterns = [
    -            re.compile(
    -                pattern.replace(
    -                    r".", r"\."
    -                ).replace(
    -                    r"*", r"[0-9A-Za-z]+"
    -                )
    -            )
    +            re.compile('^' + pattern.replace(r".", r"\.") \
    +                                    .replace(r"*", r"[0-9A-Za-z]+") + '$')
                 for pattern in (set(common_name) | set(alt_names))]
     
             return any(
    
  • libcloud/__init__.py+1 1 modified
    @@ -20,7 +20,7 @@
     """
     
     __all__ = ['__version__', 'enable_debug']
    -__version__ = '0.11.0'
    +__version__ = '0.11.1'
     
     try:
         import paramiko
    
  • libcloud/test/test_httplib_ssl.py+33 0 modified
    @@ -45,16 +45,49 @@ def test_verify_hostname(self):
              'subjectAltName': ((('DNS', 'foo.alt.name')),
                                (('DNS', 'foo.alt.name.1')))}
     
    +        cert3 = {'notAfter': 'Feb 16 16:54:50 2013 GMT',
    +         'subject': ((('countryName', 'US'),),
    +                     (('stateOrProvinceName', 'Delaware'),),
    +                     (('localityName', 'Wilmington'),),
    +                     (('organizationName', 'Python Software Foundation'),),
    +                     (('organizationalUnitName', 'SSL'),),
    +                     (('commonName', 'python.org'),))}
    +
             self.assertFalse(self.httplib_object._verify_hostname(
                              hostname='invalid', cert=cert1))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                         hostname='machine.python.org', cert=cert1))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                         hostname='foomachine.python.org', cert=cert1))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='somesomemachine.python.org', cert=cert1))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='somemachine.python.orga', cert=cert1))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='somemachine.python.org.org', cert=cert1))
             self.assertTrue(self.httplib_object._verify_hostname(
                             hostname='somemachine.python.org', cert=cert1))
     
             self.assertFalse(self.httplib_object._verify_hostname(
                              hostname='invalid', cert=cert2))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='afoo.alt.name.1', cert=cert2))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='a.foo.alt.name.1', cert=cert2))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='foo.alt.name.1.2', cert=cert2))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='afoo.alt.name.1.2', cert=cert2))
             self.assertTrue(self.httplib_object._verify_hostname(
                             hostname='foo.alt.name.1', cert=cert2))
     
    +        self.assertTrue(self.httplib_object._verify_hostname(
    +                        hostname='python.org', cert=cert3))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='opython.org', cert=cert3))
    +        self.assertFalse(self.httplib_object._verify_hostname(
    +                        hostname='ython.org', cert=cert3))
    +
         def test_get_subject_alt_names(self):
             cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT',
              'subject': ((('countryName', 'US'),),
    

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

6

News mentions

0

No linked articles in our index yet.