Boto: Creating a connection object derived from an AWSAuthConnection will ignore validate_certs=False on python2 >= 2.7.9

Created on 19 Jan 2016  路  3Comments  路  Source: boto/boto

Boto has the helpful validate_certs parameter that can be passed into connection objects that derive from AWSAuthConnection.

However, in python2 >= 2.7.9 (not sure about python3), that parameter will have no effect. The issue stems from

https://github.com/boto/boto/blob/develop/boto/connection.py#L755

which is the branch that is executed if:

  • no proxy is in use
  • a special https connection factory was not passed in
  • http_validate_certificates is not True, which will be the case if validate_certs is set to False and no overriding options were set in the Boto config.

However, that function has the following note

Changed in version 2.7.9: context was added.

This class now performs all the necessary certificate and hostname checks by default. To revert to the previous, unverified, behavior ssl._create_unverified_context() can be passed to the context parameter.

So, the default behavior changed from 2.7.8 to 2.7.9, which I believe breaks the expectations that Boto has.

The way we discovered/tested this was by trying to connect to kinesalite. I believe using any other non-validated ssl will trigger the same behavior.

Testing code is:

$ kinesalite --ssl # starts kinesalite in https mode with a self-signed cert on port 4567

# running in python

from boto.kinesis.layer1 import KinesisConnection
from boto.regioninfo import RegionInfo

regionInfo = RegionInfo(name='us-west-2',
                            endpoint='https://localhost:4567')
kwargs = {"region":regionInfo,
          "aws_access_key_id":'SOMEKEY',
          "aws_secret_access_key":'SOMESECRET',
          "is_secure":True,
          "validate_certs":False,
          "port":4567,
          "host":'localhost'
}

kinesisConn = KinesisConnection(**kwargs)
response = kinesisConn.list_streams()
print response # this should return _something_, instead the program will hang

This same code will work on python 2.7.8 but fail on python 2.7.9.

Perhaps this is also related to issue #2901?

Most helpful comment

Hi,

It's very late but as @rwdalpe mentioned, it's possible to do a workaround with https_connection_factory. Here is a sample code :

def create_factory(host):
    return (
        http_client.HTTPSConnection(
            host = host,
            port = 8000,
            context = ssl._create_unverified_context()
        )
    )

factory = (create_factory, ())

conn = S3Connection(
        "accessKey1",
        "verySecretKey1",
        host = "127.0.0.1",
        port = 8000,
        is_secure = True,
        validate_certs = False,
        calling_format = OrdinaryCallingFormat(),
        https_connection_factory = factory
)

All 3 comments

Possible (untested from my end) workaround is to pass in the https_connection_factory. That might be the only option considering that the context parameter to that constructor doesn't exist in python2 < 2.7.9, so I'm sure it might be difficult to get the correct behavior and be backwards compatible.

Also seeing this behavior with Python 3.6.1. I expect it manifests in all Python3 >= 3.4.3, according to the similar note in the python3 docs about the use of context=ssl._create_unverified_context().

Hi,

It's very late but as @rwdalpe mentioned, it's possible to do a workaround with https_connection_factory. Here is a sample code :

def create_factory(host):
    return (
        http_client.HTTPSConnection(
            host = host,
            port = 8000,
            context = ssl._create_unverified_context()
        )
    )

factory = (create_factory, ())

conn = S3Connection(
        "accessKey1",
        "verySecretKey1",
        host = "127.0.0.1",
        port = 8000,
        is_secure = True,
        validate_certs = False,
        calling_format = OrdinaryCallingFormat(),
        https_connection_factory = factory
)
Was this page helpful?
0 / 5 - 0 ratings