Fixing WordPress redirect loops and insecure links under HTTPS

March 9th, 2016

I tried to switch my blog over to HTTPS and encountered two problems:

  • My stylesheet broke because get_stylesheet_uri() (and other links) were yielding http:// links, which were blocked by the browser
  • Attempting to log in would produce a redirect loop

This was in spite of my database and config files *all* having https URLs, not http. Mysterious and upsetting.

The problem turned out to be that (as far as I can tell) my blog is run on a server behind an SSL-terminating proxy that speaks HTTP to the server. WordPress's is_ssl() function checks the value of $_SERVER['HTTPS'] to see if it is being accessed via HTTPS. WP then (apparently) writes URLs to match this instead of using the literal base URL (this seems stupid) and also generates redirects to try to match the base URL. Both of these cause the observed breakage.

My fix was to add $_SERVER['HTTPS'] = 'on' to my wp-config.

Force SSL for Wikipedia (for advanced users)

May 22nd, 2010

I like using HTTPS whenever possible. Usually this is as simple as adding a single letter to a URL, but some sites have separate domains for SSL. The Wikimedia sites are a great example of this; they share the domain secure.wikimedia.org and use the first elements of the path to specify the site.

(Edit 2016-11-25: Nowadays, you can just use the HTTPS Everywhere browser extension for Firefox, Opera, or Chrome! And you don't need to use a separate domains anymore.)

Now, I could have set up a Greasemonkey script to redirect me once I hit an unsecure Wikipedia page, but then it's too late. (I'm usually going directly to the article via web search results.) I could also use Greasemonkey to rewrite URLs in web pages, but that's a mess. Instead, I wanted to intercept any requests to unsecure Wikipedia and redirect them on the fly, before they even left my machine. Here's how I set up my browser to always use SSL for Wikimedia sites:

  1. Have Apache with virtual hosts and Mozilla Firefox with FoxyProxy
  2. In my default virtual host:
    <Directory /var/www/>
    	RewriteEngine On
    	RewriteBase /
    	RewriteCond ${HTTP_HOST} !.*mycomputername.*
    	RewriteRule . rewriter.php [L]
    </Directory>
  3. And this file at /var/www/rewriter.php:
    <?php
    
    $host = $_SERVER['HTTP_HOST'];
    $path = $_SERVER['REQUEST_URI'];
    
    // ensure path is not of form http://...
    if(strpos($path, '/') !== 0) {
    	$start = "http://$host/";
    	if(strpos($path, $start) === 0) {
    		$path = substr($path, strlen($start) - 1); // include slash
    	} else {
    		die();
    	}
    }
    
    if(preg_match('/([a-z0-9]+)\.wikipedia\.org/', $host, $m_domain)) {
    	header("Location: https://secure.wikimedia.org/wikipedia/{$m_domain[1]}{$path}");
    	die();
    }
    
    ?>
  4. Then set up a proxy in FoxyProxy, early in the chain, called "rewriter". Set it to a SOCKS 5 proxy at localhost:80, using the whitelist regex http://[a-z]+\.wikipedia\.org/.*

Obviously, the setup as written here only gets Wikipedia, but it could easily be expanded to Wiktionary, Wikibooks, Wikimedia Commons, and other sister sites.

I'll delete any tech-support questions in the comments area, so don't ask them. This guide is for advanced users only. Discussions of potential improvements are welcome.