Urllib and validation of server certificate

前端 未结 2 1366
旧巷少年郎
旧巷少年郎 2020-12-23 22:52

I use python 2.6 and request Facebook API (https). I guess my service could be target of Man In The Middle attacks. I discovered this morning reading again urllib module doc

2条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-23 23:50

    You could create a urllib2 opener which can do the validation for you using a custom handler. The following code is an example that works with Python 2.7.3 . It assumes you have downloaded http://curl.haxx.se/ca/cacert.pem to the same folder where the script is saved.

    #!/usr/bin/env python
    import urllib2
    import httplib
    import ssl
    import socket
    import os
    
    CERT_FILE = os.path.join(os.path.dirname(__file__), 'cacert.pem')
    
    
    class ValidHTTPSConnection(httplib.HTTPConnection):
            "This class allows communication via SSL."
    
            default_port = httplib.HTTPS_PORT
    
            def __init__(self, *args, **kwargs):
                httplib.HTTPConnection.__init__(self, *args, **kwargs)
    
            def connect(self):
                "Connect to a host on a given (SSL) port."
    
                sock = socket.create_connection((self.host, self.port),
                                                self.timeout, self.source_address)
                if self._tunnel_host:
                    self.sock = sock
                    self._tunnel()
                self.sock = ssl.wrap_socket(sock,
                                            ca_certs=CERT_FILE,
                                            cert_reqs=ssl.CERT_REQUIRED)
    
    
    class ValidHTTPSHandler(urllib2.HTTPSHandler):
    
        def https_open(self, req):
                return self.do_open(ValidHTTPSConnection, req)
    
    opener = urllib2.build_opener(ValidHTTPSHandler)
    
    
    def test_access(url):
        print "Acessing", url
        page = opener.open(url)
        print page.info()
        data = page.read()
        print "First 100 bytes:", data[0:100]
        print "Done accesing", url
        print ""
    
    # This should work
    test_access("https://www.google.com")
    
    # Accessing a page with a self signed certificate should not work
    # At the time of writing, the following page uses a self signed certificate
    test_access("https://tidia.ita.br/")
    

    Running this script you should see something a output like this:

    Acessing https://www.google.com
    Date: Mon, 14 Jan 2013 14:19:03 GMT
    Expires: -1
    ...
    
    First 100 bytes: 
        test_access("https://tidia.ita.br/")
      File "https_validation.py", line 42, in test_access
        page = opener.open(url)
      ...
      File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1177, in do_open
        raise URLError(err)
    urllib2.URLError: 
    

提交回复
热议问题