Cleaning up WordPress plugin script and stylesheet loads over SSL

It’s quite common to use WordPress as the host for an online shop, and that often means having an order page that needs to be encrypted via SSL. You don’t want your customers providing credit card details or other sensitive information over an unencrypted connection! But many WordPress plugins don’t take SSL into account, and merrily load scripts and stylesheets without encryption. Here’s a couple of ways to fix this problem.

Update: now available as a plugin

First of all, you might ask why this is a problem. Well, modern web browsers show some pretty scary warnings to your visitors, telling them about “insecure content” and the perils that may entail. This is a good thing! Loading scripts and other assets without encryption can undermine the secure communications you have established by loading your page over SSL.

The root cause in WordPress plugins is often that the plugin author has used the WP_PLUGIN_URL constant to locate their base folder, rather than use a function call. This constant is set right up front, before other plugins and themes get a chance to tell WordPress to switch to the HTTPS protocol to load pages. What they should be doing instead is calling plugin_dir_url or one of the other plugin URL functions, like this:

$url = plugin_dir_url(__FILE__);

To get around this with scripts and styles that are loaded via WordPress’ register and enqueue functions (which they all should, but some don’t), you can clean up the registration information after the fact but before the scripts are output. It’s a dirty hack, but it works! NB: I’m only bothering to do this on the main website, not the admin pages which I don’t need to worry about. YMMV.

// fix some badly enqueued scripts with no sense of HTTPS
add_action('wp_print_scripts', 'enqueueScriptsFix', 100);
add_action('wp_print_styles', 'enqueueStylesFix', 100);

/**
* force plugins to load scripts with SSL if page is SSL
*/
function enqueueScriptsFix() {
    if (!is_admin()) {
        if (!empty($_SERVER['HTTPS'])) {
            global $wp_scripts;
            foreach ((array) $wp_scripts->registered as $script) {
                if (stripos($script->src, 'http://', 0) !== FALSE)
                    $script->src = str_replace('http://', 'https://', $script->src);
            }
        }
    }
}

/**
* force plugins to load styles with SSL if page is SSL
*/
function enqueueStylesFix() {
    if (!is_admin()) {
        if (!empty($_SERVER['HTTPS'])) {
            global $wp_styles;
            foreach ((array) $wp_styles->registered as $script) {
                if (stripos($script->src, 'http://', 0) !== FALSE)
                    $script->src = str_replace('http://', 'https://', $script->src);
            }
        }
    }
}

Some plugins don’t play nice, and directly load their scripts and stylesheets outside of the standard practice. The Links Shortcode plugin, for example, directly writes a link for its stylesheet using the wp_head action to trigger when to write it:

add_action('wp_head', 'linkssc_css');

function linkssc_css()
{
    echo '<link rel="stylesheet" type="text/css" media="screen" href="'. WP_PLUGIN_URL . '/links-shortcode/links-shortcode.css"/>';
}

But that’s OK, we can handle that too, by replacing it with a properly enqueued script. Just add this into the enqueueStylesFix() function above:

// force links-shortcode to load CSS with SSL if page is SSL
if (function_exists('linkssc_css')) {
    remove_action('wp_head', 'linkssc_css');
    $url = plugins_url('links-shortcode.css', WP_PLUGIN_DIR . '/links-shortcode/');
    wp_enqueue_style('links-shortcode', $url);
}

It might take a little gentle persuasion, but in the end, job is done.

facebooktwittergoogle_plusredditpinterestlinkedinmailfacebooktwittergoogle_plusredditpinterestlinkedinmail
  • http://www.mitracreative.com Bill Valentine

    Thank you for this plugin. I have created websites using WP e-Commerce for two different clients and on both sites Chrome was displaying an insecure content error.

    Firefox and Safari do not show this error.

    However, Chrome now shows the https in red and crossed out and when you click on it, it still says there is insecure content. Do you know why it does that? Is there anything that can be done about it.

    thanks again

    Bill

    • http://snippets.webaware.com.au/ rmckay

      G’day Bill,

      When you click on the little cross, it displays a window that tells you what the problem is, whether it’s an untrusted certificate or insecure content. For example, my development computer has the default certificate that comes with Fedora Linux, so I get a message that “Server’s certificate is not trusted“.

      Click yours to see which problem you have, and if it’s still insecure content then please post a link to your site on the support forum and I’ll see what I can do about fixing it.

    • http://snippets.webaware.com.au/ rmckay

      Actually, I just remembered: Chrome will keep showing you that warning even after you fix the problem; you need to close Chrome and start it up again to clear the warning!

  • Pingback: WordPress Arena: A Blog for WordPress Developers, Designers and Blogger

  • https://www.moneydailynews.com/ MRFriday

    Thank you for the code and plugin.

    • http://snippets.webaware.com.au/ Ross McKay

      You’re welcome, I hope you find it useful.

      cheers,
      Ross

  • Tom Coates

    Hi,

    Thank you very much for you plugin! Lets hope the dev actually fix/ build their plugins correctly one day! :) In the mean time any chance you could add a fix for WTI Like Post? Its style sheet doesn’t seem to want to change to https.

    http://wordpress.org/extend/plugins/wti-like-post/

    Hope you can help! :)

    Thanks again!
    Tom

    • http://snippets.webaware.com.au/ Ross McKay

      G’day Tom,

      Don’t be too hard on the devs, we’re all learning as we go along (and the WordPress docs change as we learn and as WordPress changes too).

      Unfortunately, while I can fix the CSS loaded over HTTP, I can’t easily fix the pixel.gif image because it’s part of the content generation and I don’t filter page content (I want to keep this plugin as lightweight as possible). I’ll write a post on the plugin’s support forum though, and the author seems quite responsive to support posts so you will probably get an update from them soon.

      cheers,
      Ross

    • http://snippets.webaware.com.au/ Ross McKay

      G’day Tom,

      Just a thought: WordPress HTTPS will probably fix this for you. It is a bigger, heavier plugin than mine and does content filtering (AFAIK) so you should give it a try until WTI Like Post gets updated.

      cheers,
      Ross

      • http://twitter.com/coatezyuk Tom Coates

        Hi Ross,

        I guess it will probably be a gradual change. Was probably a tad harsh. The effects of 2am trying to make everything happy with SSL for just one page! :)

        Was a bit worried about using WordPress HTTPS as like you said its not so lightweight but it sounds like it might be the answer. :)

        Thank for taking the time to have a look for me!

        Cheers
        Tom

        • http://snippets.webaware.com.au/ Ross McKay

          G’day Tom,

          No worries, best of luck with your site. Keep an eye on the WTI Like Post updates as you’ll probably be able to drop WordPress HTTPS once the pixel.gif and CSS file are both fixed.

          cheers,
          Ross

  • Eskebarne

    Great plugin

    However I’m trying to use it to also secure plugin styles and scripts in the admin interface.

    I removed the !is_admin() check and it works for scripts but not styles.

    Any ideas?

    Thanks

    • http://snippets.webaware.com.au/ Ross McKay

      G’day Eskebarne,

      I hadn’t considered it necessary to deal with admin pages, since insecure content only generated a warning and didn’t affect the functionality of the page… until recent releases of some browsers. Perhaps it’s time to release a version that fixes admin scripts and styles too? Will do that this weekend.

      cheers,
      Ross

    • http://snippets.webaware.com.au/ Ross McKay

      G’day Eskebarne,

      I just released a new version that handles properly-enqueued admin stylesheets. If this doesn’t fix your problem, please let me know on the support forum which plugin is causing you problems.

      cheers,
      Ross

  • Billzy

    Thanks heaps for this fix… an issue that was previously quite frustrating. Worked fine on Multisite for me as well

    • http://snippets.webaware.com.au/ Ross McKay

      G’day Billzy, glad it worked for you, and nice to hear that it works on multisite — haven’t tried multisite yet so it’s good to get some feedback on that.

      cheers,
      Ross

  • Pingback: SSL Insecure Content Fixer: Patch Up WordPress SSL Certification

  • mings

    Hi Ross,
    Just a token of note to say Thank you very much!
    It works!

  • Igor

    This plugin made my day :)

    Tnx for creating and sharing, well done.