Note: We’ve updated this post to reflect the evolving security standards around mixed content, SSLs, and server access as a whole.
With the web’s increased emphasis on security, all sites should operate on HTTPS. Installing an SSL allows you to make that transition with your website. But it can also have an unintended consequence for sites that have been operating on HTTP previously: Mixed content warnings.
Today, let’s look at these common errors, what causes them, and how you can fix them.
What is Mixed Content?
Mixed content warnings happen when a site’s content loads through a mix of HTTP and HTTPS connections.
Typically this takes the form of the initial HTML loading via HTTPS, and then various content resources loading through HTTP.
When a browser detects mixed content, it will alert the user and potentially block the content. Here’s an example of what that might look like:
Why Does Mixed Content Matter?
Quite plainly, mixed content presents a security vulnerability. Since the communication on the HTTP connections is insecure, attackers can replace content on the website without any indication for the visitor, eavesdrop on users, and even take control of the site itself in certain cases.
Browsers increasingly take a defensive stance against mixed content. By that, I mean they’ll block access to the non-secure content or the site itself.
Scripts, iframes and stylesheets likely get outright blocked. With audio and video, a browser may try to load the asset via HTTPS first – and then block the content if it can’t. Images might still load, but deliver a warning.
In any case, your site visitors won’t experience your site as intended – or maybe not experience your site at all.
So, if you see mixed content warnings on your site, addressing the issue should be high on your priority list.
What Causes Mixed Content Warnings?
We most frequently see mixed content warnings on sites with heavy use of site assets – especially external ones – like images, media files, JavaScript, and even CSS.
Why? Two primary reasons:
- URLs to those files are hardcoded in the site
- Default configurations load these assets over HTTP
So, when a site gets updated to HTTPS those paths still link to the HTTP version.
As far as how that looks in a site’s code: This can happen when the absolute URL path is set, instead of relative paths for images, CSS, or JavaScript files.
Absolute path:
<img src="http://mydomain.com/myimage.png">
Relative path:
<img src="/myimage.png">
How Do I Unblock Mixed Content?
Every browser that allows for unblocking mixed content will also provide a tutorial on how to do it. However, given what we’ve learned about the potential malicious use of mixed content, I can’t recommend doing this. Even if your site has a small user base who you could instruct to unblock the mixed content, you’re opening them up for a potentially harmful attack.
In the end, putting in a little effort to fix the issue will be easier than trying to avoid it!
How to Fix Mixed Content in WordPress
Use the really-simple-ssl Plugin
If you’re using the WordPress CMS, you are in luck because you can make use of the really-simple-ssl plugin. It will automatically fix all your schemes and redirect HTTP to HTTPS on your behalf.
There’s a premium version as well, which will report on any mixed content issues that couldn’t be resolved automatically, fix back-end issues, add security headers, and more.
After installation and activation, the tool will show you the following screen:
The tool will automatically log you out of WordPress and force HTTPS on your website.
Note: For WordPress users, one of my all-time favorite resources to point to is on the ManageWP blog – WordPress SSL Settings and How to Resolve Mixed Content Warnings. I encourage you to give it a review as it provides a number of great discussion points.
How to Find and Fix Mixed Content Issues in Generic Files
If your site’s CMS template and/or files are in HTML or PHP files, you can find and fix mixed content issues by conducting the following steps:
1. Conduct a Mass Search
If you know how to use terminal commands, a grep command can help you identify every file that references a http://. Be sure to be in the root of your website (i.e., /public-html/, /www/html/, etc..):
$ grep -r “http://yourdomain.com/”
If you’re looking for a less technical way to assess your site, run a scan with a tool like WebPageTest. In the results, look for content elements that do not show up with a padlock next to them (like number 2 in this screenshot).
Our own SiteCheck tool will also report on mixed content. You’ll find these noted under TLS Recommendations, as you see below.
2. Replace Your Content
You’ll then change all references to http:// to include https://.
How to Find and Fix Mixed Content Issues in Your Database
Depending on the platform you choose, your website technology might dynamically render the asset locations in the database. So you’ll want to go directly to the database and update all protocol references.
Here are some quick tips to find and fix mixed content in your database:
Get a Database Search and Replace Tool to Identify and Replace Mixed Content
There is a great tool called Database Search and Replace, built by Interconnected/IT. As the name implies, it allows you to do a quick search of your database, replacing values as needed. Of course, be careful.
Configure Database Search and Replace
Download the Database Search and Replace tool at the root of your website:
[root@server [domain directory]# wget https://github.com/interconnectit/Search-Replace-DB/archive/master.zip [root@server [domain directory]# unzip master.zip [root@server [domain directory]# cd Search-Replace-DB-master/
Once you have installed the tool, you can access it directly by going to http://yourdomain.com/Search-Replace-DB-master/index.php
When you load the tool, it will pull the values from your /wp-config.php. If for whatever reason it doesn’t, here is how you map the values:
Name = define('DB_NAME', User = define('DB_USER', Password = define('DB_PASSWORD', Host = define('DB_HOST', Port = Default 3306
Run Search and Replace
When running “search and replace” be mindful of all the things you can inadvertently break. To account for this, I recommend being as specific as possible. For instance, in the image above, you can see I search for http://yourdomain.com and replace with https://yourdomain.com. This is an effort to avoid breaking any other http references that might cause unexpected issues.
Even then, before you run the tool, please be sure to have a database backup.
The tool also helps by giving you two very distinct options: Dry Run and Live Run. I recommend running a Dry Run first, checking the output, then running a Live Run if everything works well.
Identify and Handle HTTPS Traffic
Next you want to make sure that your server/website is ready to handle HTTPS traffic. Of course, the first step is to install your SSL certificate. If you’ve done that, you can then take the next step using really-simple-ssl or directly through your /wp-config.php file.
/* Handle HTTPS Protocol */ if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on';
This will make it so that your website/server accepts all HTTPS requests, and it also enables HTTPS on your website. There are obviously a number of different deployment types. For more variations you can reference this Codex article on WordPress.org.
When done, clear any caches you might have enabled and visit your website. You should now get the secure padlock in the browser without any mixed content warnings:
Remove Database Search and Replace Tool
Please, whatever you do, do not forget to remove the DS&R tool from your root once you have found and fixed all your mixed content issues. Leaving it on your server could introduce itself as a potential attack vector later.
Customer Support
If you’re an existing Sucuri customer and are having issues getting things configured please connect with our team by submitting a ticket. If you are deploying LetsEncrypt locally here is a simple guide to help get you started.