tags:

views:

86

answers:

2

I have Python code to call a REST service that is something like this:

import urllib 
import urllib2 

username = 'foo' 
password = 'bar' 

passwordManager = urllib2.HTTPPasswordMgrWithDefaultRealm() 
passwordManager .add_password(None, MY_APP_PATH, username, password) 
authHandler = urllib2.HTTPBasicAuthHandler(passwordManager) 
opener = urllib2.build_opener(authHandler) 
urllib2.install_opener(opener) 

params= { "param1" : param1, 
          "param2" : param2, 
          "param3" : param3 } 

xmlResults = urllib2.urlopen(MY_APP_PATH, urllib.urlencode(params)).read() 
results = MyResponseParser.parse(xmlResults) 

MY_APP_PATH is currently an HTTP url. I would like to change it to use SSL ("HTTPS"). How would I go about changing this code to use https in the simplest way possible?

+1  A: 

Unfortunately, urllib2 and httplib, at least up to Python 2.7 don't do any certificate verification for when using HTTPS. The result is that you're exchanging information with a server you haven't necessarily identified (it's a bit like exchanging a secret with someone whose identity you haven't verified): this defeats the security purpose of HTTPS.

See this quote from httplib (in Python 2.7):

Note: This does not do any certificate verification.

(This is independent of httplib.HTTPSConnection being able to send a client-certificate: that's what its key and cert parameters are for.)

There are ways around this, for example:

Bruno
+1  A: 

Just using HTTPS:// instead of HTTP:// in the URL you are calling should work, at least if you are trying to reach a known/verified server. If necessary, you can use your client-side SSL certificate to secure the API transaction:

mykey = '/path/to/ssl_key_file'
mycert = '/path/to/ssl_cert_file'
opener = urllib2.build_opener(HTTPSClientAuthHandler(mykey, mycert))
opener.add_handler(urllib2.HTTPBasicAuthHandler()) # add HTTP Basic Authentication information...
opener.add_password(user=settings.USER_ID, passwd=settings.PASSWD)
Dick
Except that it's not secure... You need to verify the *server* certificate first.
Bruno
Hmm, shoot, you're right.
Dick