WordPress SSL Settings and How to Resolve Mixed Content Warnings
Building a website consists of a varied number of steps, depending on the owner, creator, manager, type of site, and audience.Everyone cares about security and wants a positive user experience. No one likes to see “site down” error messages or web browser warnings.
Below, you can learn about serving secure web pages and secure assets (like images, scripts, and forms) and how to find and resolve browser security errors.
The Basics of HTTPS
Forms that receive sensitive user information – like credit cards, login information, or confidential user feedback – need to be submitted securely, via HTTPS. An SSL certificate is purchased and installed on your web server to enable HTTPS browsing.
SSL certificates range from $10 to $1,000+ per year, providing different levels of verification and browser integration (e.g. it costs more to turn the browser bar green). All price ranges enable HTTPS browsing, which permits secure browsing, assuming the SSL certificate is valid and that the website is trusted by the visitor.
Pages can be served via HTTP while still including HTTPS forms. This practice allows for form submissions to be submitted securely while still enabling caching (for site speed), or for other reasons. However, the downside to this method is that the visitor has been trained to look for a padlock icon or a green bar displayed within the browser, which only happens when pages are served via HTTPS (i.e. when HTTPS is in the browser’s address bar).
But the browser gives warnings for webpages served via HTTPS that include HTTP assets, like scripts, forms, and images. To avoid these browser warning messages, you need to make sure that you don’t serve any HTTP assets on an HTTPS page. Browser warning messages may put some of your site visitors on high alert, causing them to not complete that shopping cart order or that contact form.
WordPress HTTPS
After installing a valid SSL certificate onto your server (your host can help with that), there are 3 ways to implement HTTPS into your WordPress site.
Option 1: Forcing All Pages to HTTPS
Although this is the easiest option, it’s not always the right option because caching isn’t enabled for HTTPS pages. If you’re sure you want to serve every page of your WordPress site via HTTPS, just go to your WordPress General Settings and change the WordPress Address (URL) and the Site Address (URL) from HTTP to HTTPS.
Option 2: Forcing Certain Pages to HTTPS (most common)
More often than not, there are only a few pages you want to force load via HTTPS, and the rest should be loaded via HTTP by default. While there are server-side ways to enable this, there are also a few plugins that provide the ease of a check box. You check the box if you want the page loaded via HTTPS, or you leave it unchecked. Here are a couple of plugins to choose from:
Option 3: Force HTTPS logins or Force HTTPS logins and HTTPS administration
If you’re looking for a simple way to secure WordPress logins (the wp-login.php script) or the entire wp-admin area, you could set one of these two wp-config.php constants, respectively:
define('FORCE_SSL_LOGIN', true); define('FORCE_SSL_ADMIN', true);You do not need to set both of these options, just one or the other because FORCE_SSL_ADMIN includes FORCE_SSL_LOGIN.
How to Identify HTTP Assets Loaded on an HTTPS Page
Here’s the nitty gritty section you’ve been waiting for.
- You already have your SSL certificate installed correctly, and you can browse your site via HTTPS by manually typing it into the address bar.
- You have your HTTPS plugin(s) and/or wp-config.php constant(s) setup and working.
- But the browser throws intimidating warning messages about “mixed content” or “insecure content” loaded on an HTTPS page.
Following are several ways to identify the insecure (HTTP) assets loaded on secure (HTTPS) pages. You may need to use several of these methods to resolve all your browser security warnings about mixed content.
Note: Option 4 is my favorite!
Option 1: View Source
This method is pretty simple. Load the page via HTTPS; right-click anywhere on the page; and click “View Page Source”, “View Source”, or “Source”, depending on your browser.
Then use the “Find” command (Edit -> Find or Ctrl+F or Cmd+F) and search for:
src="http:(with double-quote)
src='http:(with single-quote)
Long story short, you’re manually looking for images, scripts, iframes, and all other assets served via HTTP instead of HTTPS. If you don’t find any with either double- or single-quote HTTP:, then you’re all done with that page. Keep browsing to other HTTPS pages and keep searching through View Source.
Option 2: Use a Plugin
A couple plugins exist that essentially do the View Source for you:
- WordPress HTTPS (SSL) (mentioned above too)
- WordPress HTTPS Test
- SSL Insecure Content Fixer
Basically, you browse your site via HTTPS with one of these plugins active, and the plugin displays notifications of the HTTP assets. Some plugins show the warnings for all visitors and some only display to Administrators so beware of leaving these sort of plugins active while you’re not testing.
Option 3: Paste the URL into a Website that Tests for Insecure Assets
If you don’t want to View Source and don’t want to enable a plugin (maybe because it displays to all visitors, not just administrators), then you could paste your page’s URL into a website that tests it for you.
WhyNoPadlock is a free testing site that provides you with a report of all the insecurely-loaded items. It provides an easy-to-understand list of green check marks or red x’s. Pay attention to the red x’s; fix them in your plugins or theme; and click the “Test URL Again” button to try and rid yourself of red x’s. Once done with that page, paste in a different URL to see if it’s also free from red x’s. Wash, Rinse, Repeat.
Option 4: Use Google Chrome Inspector Console (My Favorite Way)
Google Chrome’s Inspector has a Console tab. If the HTTPS page you’re displays yellow or red in the address bar (see 3rd and 4th icons below), open the Console to see the one or multiple insecure assets.
This is my favorite method because it’s quick, easy, and can be used on any page I can access, not just on the front-end like WhyNoPadlock. It’s basically like Option 1: View Source but with Chrome finding the issues for me.
How to Fix Insecurely-Loaded Assets
Make note of each item sourced via HTTP and you’ll get an idea where to find the problem. Here are some examples:
- A plugin loading a JavaScript file via HTTP: http://example.com/wp-content/plugins/example-plugin/awesome.js
- The active theme loading an insecure image file: http://example.com/wp-content/themes/example-theme/assets/images/circle.png
- The active theme (most likely in functions.php, but it could be loaded via a plugin instead of the theme) loading Google fonts insecurely: http://fonts.googleapis.com/css?family=Lato:100,400,700
- Notice even insecure assets from outside your WordPress installation throw browser errors.
What You Now Know
You now know that the plugin or theme you’re using isn’t coded properly. It may be a quick fix or need significant modification. Before working on fixing it, you have to ask yourself, “Do I really need this?” because if this is wrong, I bet other things are wrong. Sometimes an uninstall can be healthy.
If you decide the plugin or theme is worth keeping, start working to fix these errors.
You have a few options per asset:
- Report the error to the plugin developer and leave deactivated for now.
- Edit the plugin files yourself, sharing the fix with the plugin developer.
- Change to a different theme
- Edit the current theme’s files (hint: start looking in functions.php)
Personally, if a plugin throws WP_DEBUG errors, sets off security errors, or loads assets on pages where it doesn’t belong, I usually get rid of it altogether. If I have the time and the plugin is valuable enough, sometimes I report the error or even provide the fix, especially if the plugin author has enough credibility that I know this is an infrequent occurrence.
How to Change Assets from HTTP to HTTPS
After discovering the offending assets, you need to change them to either respect the protocol (i.e. serve HTTP when the page is HTTP and serve HTTPS when the page is HTTPS) or change them to always be served via HTTPS, even for pages loaded with the HTTP protocol. These 2 steps should cover all scenarios. You might only need Step 1 or Step 2 to resolve the insecure warning issues.
Step 1: Use Relative URLs
This is the simplest fix. If an asset (image, script, etc.) is hard-coded into a plugin or theme, change it from ‘http://site.com/assets/logo.png’ to ‘//site.com/assets/logo.png’.
Typically, this is most useful when including assets from other servers, like Google scripts, API scripts, or iframes.
Before doing this, however, you need to make sure the HTTPS version is available. If loading an asset from a site that doesn’t have HTTPS enabled, it’s probably best to remove the reference entirely (i.e. comment out or delete) or to save the asset to your own server and change the source to load via your site instead.
Step 2: Use Proper WordPress Coding Standards
This issue is a bit more complicated. I’ve seen all kinds of things, like:
- Code that forces HTTP (why?!)
- Using deprecated WordPress functions that don’t respect SSL settings
- Code that tries (and fails) to implement its own “if is HTTPS” logic instead of using the WordPress functions
Each of these types of errors could take some time to resolve. Here are some helpful WordPress functions that may need to be used instead of the current code:
- home_url() and related functions
- is_ssl()
- WordPress Function Reference (stay away from the ones in red; they are deprecated)
- WP_DEBUG might help too
Conclusion
Here are the bullet points:
- If you’re going to have an SSL certificate and serve one or more pages via HTTPS, work hard to resolve all “mixed content” warnings to provide your visitors with a pleasant browsing experience (especially Internet Explorer users because IE’s warnings are the most in-your-face).
- If a WordPress extension (plugin / theme) isn’t coded properly for SSL, do you really want to use it?
- If it was free, report the problem and try to help provide the solution.
- If it was not free, report the problem and consider if it was really worth your money. Maybe you should ask for a refund and find another alternative.
- Once you resolve a single page’s mixed content warnings, keep browsing the site and testing each page individually, whether by using View Source, a plugin, or a testing website.
If this is too much work for you and you’re comfortable with visitors receiving mixed content warnings and you do nothing else other than install an SSL certificate, make sure to at least force secure logins. I think everyone should do this. ManageWP does.
Please share your questions and comments below.
Creative Commons images courtesy of Brenda Clarke and Jakob Montrasio