Moving WordPress onto HTTPS

So recently I’ve been moving a fair few WordPress sites over to run completely on HTTPS and whilst this should be a simple URL switch, WordPress can make it a bit of a pain. Therefore, below is my preferred way of making the transition.

For the sake of this post, I’m going to assume you’ve already purchased and installed your SSL certificate (if you haven’t Namecheap are great!)

Step 1 – Site Address Change

This is the most basic step and will change all your WordPress URLs for you.

In your wp-admin section, go to Settings > General and change these two boxes to the URLs begin with https rather than http. Easy!

Screen Shot 2016-02-23 at 23.24.16

Step 2 – Asset URL Fix

You’ve probably noticed that although your site is now running over https, you’ve not got that nice green padlock, or alternatively it’s only appearing on certain pages. Damn! Let’s fix that for you.

The reason this is happening, is because all your assets (images etc.) that have been uploaded into posts or pages, store the full URL to the file. Because when you uploaded them your url started with http your assets were saved with the http URL.

Don’t despair, we can fix this pretty easily. You’ll need to install and activate a plugin called Better Search Replace, this plugin will allow you to find and replace content in your database and although this is fairly safe, it’s probably worth backing up your database before we go any further.

Screen Shot 2016-02-23 at 23.32.49

Once installed, go to Tools > Better Search Replace in your admin area. You want to add your domain with /wp-content on it in the Search For field, E.G. In the Replace With field, you want the same thing, but with the https version of the URL, E.G. Make sure you highlight all your tables in the Select tables section and 100% make sure that the Run as dry run? checkbox IS checked.

Screen Shot 2016-02-23 at 23.35.21

Now you can click the button at the bottom to run the search. It may take a few minutes depending on the size of your database and speed of the server, but it shouldn’t take too long. Once it’s finished, if you scroll to the top of the page, you should see something like the following.

Screen Shot 2016-02-23 at 23.41.52

Feel free to click to view more details if you’d like to check which tables contain the data to be changed.

Once you’re happy with this, you can scroll back down and uncheck the Run as dry run? checkbox. Now when you hit the button to run the script, it WILL replace the data in your database.

You may need to do this for the www. version of your site as well, depending on how your site is set up, E.G. Find and replace with

Step 3 – Check Your Site

Now we’ve made it this far, it’s a good time to check that your site is still functioning correctly and that your SSL is working. If it is, great! If it’s not, then you need to look at what’s not working.

If your site is not working at all, then you’ve probably messed something up with the database find and replace. Go ahead and restore that backup you took earlier, you did take a backup didn’t you? Good.

If the site is working correctly, but your SSL is still not working as expected (no green padlock) then we need to dig deeper. Go and do a dry run search and replace on your database for the http version of your site again, you shouldn’t get any hits this time, if you do then repeat step 2 until you don’t.

If you don’t get any hits, then generally it means that something you’re using is built badly. This is normally a hardcoded CSS or JavaScript URL in your theme or a plugin you’re using. If you can, try deactivating your plugins 1 by 1 until you find the culprit, then contact the plugin author and tell them to sort their code out!

Step 4 – Force SSL Site Wide

You can skip this step if you’d prefer, but seeing as we’re installing the SLL site wide, we might as well enforce it.

To do this, you’re going to need to update your .htaccess file. If you can access this through FTP or a control panel, do it that way. If not, you can use this plugin, but it’s a little risky if you mess something up.

Whichever way you do it, you’ll need to add the following code, but make sure you switch the URL for your new https URL:

<IfModule mod_rewrite.c>
RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$$1 [R=301,L]

You’ll need to add this above the # BEGIN WordPress line that should already be in the .htaccess file.

Step 6 – Check the Site Again

Now we’ve completed all the steps, check your site again. If you’re getting a 500 error then something is wrong with your .htaccess file. Revert your changes and ask someone who knows about development to take a look at it, .htaccess files can be a pain in the ass!

If your site is now running well over SSL then well done and we’re at the end of our journey together. Enjoy your secure site and let people thing you’re a genius!

How to allow SVG uploads in WordPress


Nope, stop.

You developers/bloggers who keep passing the below code around as a valid way of allowing SVG uploads in WordPress are killing me inside.

function cc_mime_types($mimes) {
    $mimes['svg'] = 'image/svg+xml';
    return $mimes;
add_filter('upload_mimes', 'cc_mime_types');

Yes, this will allow you to upload SVGs in WordPress, it will also allow someone to upload an XML Bomb or an SVG with an XXE attack or god forbid a lovely XSS attack. You see, too many developers are allowing SVG uploads without thinking about what that means. Seriously, why do you think WordPress hasn’t added SVG uploads into core yet? Not because they want to make life difficult but because they understand the security risks that are imposed by allowing an SVG to be uploaded.

There is currently, as far as I’m aware, no well tested PHP library for SVG sanitisation. There have been a few attempts but as far as I can tell, they’ve all been far too lenient on allowing potentially dangerous attributes through. To me, this means they either are too trusting, or don’t fully understand the potential payloads that can be embedded within an SVG.

The library I’ve been working on has taken the opposite stance. By default, be overly aggressive when stripping attributes and elements and then allow people to add their own whitelist if they need to. This, I think is the only feasible way of properly sanitising an SVG.

As for WordPress and SVGs, please stop using the above code. It makes me cringe every time I see it, especially when I think that this is actually in use on production sites. Fine, play with SVGs locally but to put this on a public facing server? Well, you’re a braver person than me.

Please people, use SVGs in your front end builds, use it as backgrounds, images, inline, whatever, but please stop allowing people to upload un-sanitised SVGs to the system. There’s no difference between allowing an SVG upload to allowing a PHP upload. For those of you that think that allowing a PHP upload is OK, because there’s obviously a fair few of you please stop developing. Seriously.


Sanitize SVGs in WordPress

So my plugin Safe SVG has just been accepted into the WordPress plugin directory. Whilst mainly a proof of concept, I’m hoping that this plugin will help convince the core team that SVGs, with the right sanitization should become part of core.

My major argument for allowing SVGs in core with sanitization is that there are currently 128 other SVG upload plugins in the plugin directory (source), plus the likes of the posts on blogs like CSS Tricks such as this one that all show you how to allow SVG uploads in WordPress, but don’t address or sometimes even mention the massive security risks that come with allowing users to upload SVGs.

SVGs should be considered as standalone XML applications, there are a huge number of vulnerabilities that can be attacked. For example, some of the easiest to implement are XXE attacks and the Billion Laughs attack. Safe SVG nullifies these attacks by removing the DOCTYPE from the SVG file, something so simple yet overlooked by most other plugins.

Safe SVG also protects against XSS attacks embedded within the XML file by defining a strict whitelist of elements and attributes allowed within the SVG, anything not on these whitelists are removed. Whilst this may break some Javascript powered SVG animations, I feel that is a small price to pay for peace of mind when it comes to your users security.

Probably the best way to learn more about Safe SVG is to go and download it from the WordPress plugin directory and take a look through the code, alternatively you can see the library it’s built upon on Github. If you find a bypass or have any suggestions on how to improve this plugin or the underlying library, please don’t hesitate to contact me and let me know your thoughts.