Share the Knowledge
RSS icon Home icon
  • How to automatically redirect the WordPress login and admin pages from HTTP to HTTPS

    Posted on November 16th, 2011 webmaster No comments         Print Print

    I always get worried every time I have to login to a website over a non-SSL enabled connection.  When my blog didn’t support SSL (before I migrated from a shared host to my own VPS) and I had to work on it at a coffee shop, I would sometimes change my password when I get home, which of course is still not that secure as my blog is hosted outside my local network which I have no control over.

    A computer with a network card (wired or wireless) that supports promiscuous mode can easily sniff out packets coming in and out of other devices on the same local network the computer belongs to using tools like Wireshark.  So if you’re using a public wireless access point, for example, other computers connected to that same wireless access point could see the data you’re sending and receiving over the network.

    Even if the login form hashes the password first (using one-way hashing algorithms such as MD5 or SHA-1), most users probably have passwords that aren’t that strong/complex, allowing the attacker to brute-force the hashed passwords in a reasonable amount of time.  Advancement in GPU technology and tools like IGHashGPU make cracking passwords much, much faster.

    There are also tools like Firesheep for Firefox which allows attackers to impersonate you by hijacking your session cookies since its content can be retrieved in plain text over an unencrypted connection.

    Automatically redirecting all WordPress pages that send out authentication-related information from HTTP to HTTPS could prevent these types of attacks.

    If you have full control over your WordPress installation, this is very easy to do.  Just edit the wp-config.php file in the root directory of your WordPress installation and add the highlighted line below before /* That’s all, stop editing! Happy blogging. */.

    define('WP_DEBUG', false);
    
    /**
    * Force SSL on login and admin pages.
    */
    define('FORCE_SSL_ADMIN', true);
    
    /* That's all, stop editing! Happy blogging. */
    
    /** Absolute path to the WordPress directory. */
    if ( !defined('ABSPATH') )
            define('ABSPATH', dirname(__FILE__) . '/');
    

    More information can be found here: http://codex.wordpress.org/Administration_Over_SSL

    If you don’t have full control over your WordPress installation (such as in a shared hosting environment), you can give this plugin a try: http://wordpress.org/extend/plugins/wordpress-https/

  • How to use client certificate authentication with Suds

    Posted on July 15th, 2011 webmaster No comments         Print Print

    This is related to my last post.  I was finally able to communicate to an SSL-enabled SOAP service with my computer behind a proxy but then ran into another problem: certificate-based authentication.

    Suds actually doesn’t support certificate authentication directly, but fortunately someone created a custom transport for it: http://stackoverflow.com/questions/6277027/suds-over-https-with-cert

    I tried his code but then ran into connection issues again, I had to modify it a little bit to include the proxy settings in the transport. Here’s the slightly modified code, I basically just added a proxy handler to his transport:

    import urllib2 as u2
    from suds.client import Client
    from suds.transport.http import HttpTransport, Reply, TransportError
    import httplib
    
    class HTTPSClientAuthHandler(u2.HTTPSHandler):
        def __init__(self, key, cert):
            u2.HTTPSHandler.__init__(self)
            self.key = key
            self.cert = cert
    
        def https_open(self, req):
            # Rather than pass in a reference to a connection class, we pass in
            # a reference to a function which, for all intents and purposes,
            # will behave as a constructor
            return self.do_open(self.getConnection, req)
    
        def getConnection(self, host, timeout=300):
            return httplib.HTTPSConnection(host, key_file=self.key,
                                           cert_file=self.cert)
    
    class HTTPSClientCertTransport(HttpTransport):
        def __init__(self, key, cert, proxy_settings=None, *args, **kwargs):
            HttpTransport.__init__(self, *args, **kwargs)
            self.key = key
            self.cert = cert
            self.proxy_settings = proxy_settings
    
        def u2open(self, u2request):
            """
            Open a connection.
            @param u2request: A urllib2 request.
            @type u2request: urllib2.Requet.
            @return: The opened file-like urllib2 object.
            @rtype: fp
            """
            tm = self.options.timeout
    
            https_client_auth_handler = HTTPSClientAuthHandler(self.key,
                                                               self.cert)
    
            # Add a proxy handler if the proxy settings is specified.
            # Otherwise, just use the HTTPSClientAuthHandler.
            if self.proxy_settings:
                proxy_handler = u2.ProxyHandler(self.proxy_settings)
                url = u2.build_opener(proxy_handler, https_client_auth_handler)
            else:
                url = u2.build_opener(https_client_auth_handler)
    
            url = u2.build_opener()
    
            if self.u2ver() < 2.6:
                socket.setdefaulttimeout(tm)
                return url.open(u2request)
            else:
                return url.open(u2request, timeout=tm)
    
    # Test #
    if __name__ == '__main__':
        key= r'D:\key_nopass.pem'
        cert = r'D:\cert.pem'
        proxy_settings = {'https': 'http://user:password@host:port'}
        transport = HTTPSClientCertTransport(key, cert, proxy_settings)
    
        service_url = 'https://services.domain.com/test/hello.wsdl'
        client = Client(service_url, transport=transport)
        print client
    

    His code also only supports certificates/keys in PEM format so you may need to convert your client certificate.  In our case, we were issued a PKCS#12 certificate and we had to extract the key and certificate to PEM format using OpenSSL:

    Extract the key:

    openssl.exe pkcs12 -nocerts -in ClientCert.p12 -out key.pem

    Extract the certificate:

    openssl.exe pkcs12 -clcerts -nokeys -in ClientCert.p12 -out cert.pem

    You may also want to remove the passphrase from the key:

    openssl.exe rsa -in key.pem -out key_nopass.pem
  • How to connect to a SOAP-based web service with Suds over a proxy that requires authentication

    Posted on July 14th, 2011 webmaster 1 comment         Print Print

    I’m writing a small Python program to connect to a SOAP-based web service using Suds and just ran into an issue with authenticating to our proxy server.  I’m able to connect fine if the web service runs on http, but the web service we need to connect to uses https and the urllib2 module threw an error:

    urllib2.URLError: <urlopen error Tunnel connection failed: 407 Proxy Authentication Required>

    The solution in my case is to upgrade to a newer patch version of Python 2.6 (I upgraded mine to 2.6.6), it looks like the older urllib2 module that I was using didn’t support  this scenario as mentioned here, so make sure first that you have at least Python 2.6.4 before trying the sample code below:

    
    from suds.client import Client
    
    service_url = 'https://services.domain.com/test/hello.wsdl'
    
    proxy_settings = dict(http='http://user:password@host:port',
                          https='http://user:password@host:port')
    
    client = Client(service_url, proxy=proxy_settings)
    
    print client