Posted by: Eric Hansen
Python is an ever increasing popular language that is gaining a lot of ground in server management and such. I’ve even really started using it in writing tools and scripts due to it’s shear power you have with it compared to Bash, Perl and PHP. However, one issue I’ve had with Python, at least in the 2.x branch, is verifying that a SSL certificate is valid.
Python has a HTTP library called urllib, which when Python is compiled with SSL support also allows HTTPS connections to be made. However, in the docs for urllib it mentions one caveat: “When opening HTTPS URLs, it does not attempt to validate the server certificate. Use at your own risk!”
One of the main advantages in using HTTPS is that your data is kept confidential. One of the ways to do this is to ensure that you are using the proper SSL certificate. This involves two methods: (1) checking that the certificate is signed by a proper authority and (2) making sure that the certificate being used is for the proper (sub)domain.
In regards to method 1 above, a situation can arise where you are using a self-signed certification, which it would then fail as self-signed certifications are never validated correctly. As long as you the certificate key (usually a .pem) file, you can pass it along as an argument by doing:
To circumvent this issue with Python and HTTPS certificate validation, there is a library, Requests. It’s essentially a wrapper for Python’s httplib (another built-in module) which does a lot of the grunt work for you. httplib does give you the option to verify the certificate, but it also requires a bit of code to get it done yourself. Requests does all of the work for you, you just have to tell it you want verification done.
As an example, we will do a certification test for my business:
>>> import requests
>>> req = requests.get(“https://www.securityfor.us”, verify=True)
>>> print req
If the verification was successful, you’ll receive the “Response ” message. However, if it fails, you’ll receive an exception stating the domain provided (in this case www.securityfor.us) does not match *.domain.tld or domain.tld.