DEV Community

Cover image for Mixed Content: Why Your HTTPS Padlock Might Be Lying
Jonathan Pimperton
Jonathan Pimperton

Posted on • Originally published at sitevett.com

Mixed Content: Why Your HTTPS Padlock Might Be Lying

Mixed Content: Why Your HTTPS Padlock Might Be Lying

You've just finished a site migration or update for a client. You've meticulously set up SSL, switched your WordPress site to HTTPS, and proudly see the padlock icon in the browser bar. Then, a user reports a security warning or a broken image. The padlock, that symbol of trust and security, is actually a liar. This is almost certainly due to mixed content.

Mixed content occurs when a page is loaded over HTTPS, but some of its resources (images, scripts, stylesheets, fonts, iframes) are loaded over insecure HTTP. Modern browsers, for good reason, flag this as a security risk. They can't guarantee the integrity or authenticity of these mixed resources, potentially exposing users to man-in-the-middle attacks or data leakage. For web developers and agencies, this is a critical issue that erodes user trust and impacts SEO.

Identifying Mixed Content with Browser Developer Tools

The first step is always diagnosis. Your browser's developer tools are your best friend here. For most modern browsers (Chrome, Firefox, Edge, Safari), you can open the developer tools by pressing F12 or right-clicking on the page and selecting "Inspect" or "Inspect Element."

Once the console is open, navigate to the "Console" tab. When you load your HTTPS page, any mixed content issues will be reported here with clear warnings. They usually look something like this:

Mixed Content: The page at 'https://your-domain.com/' was loaded over HTTPS, but requested an insecure script 'http://insecure-resource.com/script.js'. This request has been blocked; the content must be served over HTTPS.
Enter fullscreen mode Exit fullscreen mode

Pay close attention to the URLs listed in these warnings. They’ll tell you exactly which resource is causing the problem and its original HTTP address.

Common Culprits and How to Find Them

Mixed content usually stems from one of three areas:

  1. Hardcoded HTTP URLs in Content: This is the most frequent offender. When content was originally created or imported under HTTP, any embedded images, videos, or links might retain their HTTP prefixes. This can happen in post content, page content, custom fields, or even in the WordPress Customizer's CSS.
  2. Theme or Plugin Files: Less common, but still possible, are themes or plugins that have hardcoded HTTP URLs for their own assets (like images in widgets, CSS background images, or JavaScript files).
  3. Third-Party Embeds: Iframes from external sources (like old YouTube embeds or third-party widgets) might be pointing to HTTP URLs.

To locate these, you'll often need to cross-reference the console warnings with your site's data.

Fixing Mixed Content: Strategies and Tools

Once you've identified the problematic resources, it's time to fix them.

1. Database Search and Replace

For hardcoded HTTP URLs in your content, a database search and replace is the most effective method. Crucially, always back up your database before performing any direct modifications.

You can use a reliable plugin like "Better Search Replace" for this within the WordPress admin, or execute SQL queries directly if you’re comfortable with that.

If using a plugin, install and activate "Better Search Replace." Navigate to "Tools" > "Better Search Replace."

  • Search for: http://your-domain.com (replace with your actual HTTP domain)
  • Replace with: https://your-domain.com (replace with your actual HTTPS domain)
  • Select all tables and run a "dry run" first to see what would be changed.
  • If the dry run looks correct, uncheck "Run as dry run?" and click "Run Search/Replace."

Alternatively, if you have SSH access and are comfortable with WP-CLI, this is a very powerful and safe way to do it:

wp search-replace 'http://your-domain.com' 'https://your-domain.com' --recurse-objects --all-tables --dry-run
Enter fullscreen mode Exit fullscreen mode

After verifying the dry run:

wp search-replace 'http://your-domain.com' 'https://your-domain.com' --recurse-objects --all-tables
Enter fullscreen mode Exit fullscreen mode

Remember to replace your-domain.com with your actual domain. If your site uses www. or not, be consistent.

2. Protocol-Relative URLs (When Appropriate)

For external resources that support both HTTP and HTTPS, you can use protocol-relative URLs. This means using // instead of http:// or https://. The browser will then automatically use the protocol of the parent page.

For example, if a script is loaded as:
<script src="http://example.com/script.js"></script>

You can change it to:
<script src="//example.com/script.js"></script>

This is particularly useful if you're not entirely sure if the external resource always supports HTTPS, but you want to ensure it defaults to HTTPS when the main page is HTTPS. However, many modern CDNs and external services now strongly prefer or require explicit HTTPS.

3. Forcing HTTPS for Specific Resources

If a theme or plugin is loading a specific resource over HTTP, and you can't easily modify its code or the database doesn't cover it (e.g., a specific image in a widget that’s hardcoded and not in the post content), you might need to force HTTPS.

This can sometimes be done through theme options or plugin settings if they provide them. If not, and the resource is a stylesheet or script, you might need to use a plugin that handles mixed content redirection, or in more advanced cases, consider enqueueing scripts/styles correctly in WordPress using functions.php to ensure they are loaded via HTTPS.

For images or other assets within theme files, you might edit the theme's template files directly (preferably in a child theme) to change http:// to https://.

// Example in functions.php to enqueue a script via HTTPS if it was previously HTTP
function my_force_https_scripts() {
    wp_enqueue_script( 'my-script-handle', 'https://example.com/my-script.js', array(), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_force_https_scripts' );
Enter fullscreen mode Exit fullscreen mode

4. Theme and Plugin Updates

Always keep your themes and plugins updated. Developers are constantly patching these kinds of issues in newer versions. If you find mixed content originating from a third-party theme or plugin, check if an update is available. If it’s custom code or an older, unmaintained plugin, you may need to refactor it.

After making any changes, always clear your website’s cache (plugin cache, server cache, CDN cache) and your browser cache to ensure you’re seeing the most up-to-date version of the page. Then, re-check the console in your developer tools to confirm all mixed content warnings are gone. The padlock should now be honest.


SiteVett checks this automatically as part of a free website QA scan with 60+ checks across security, SEO, content, performance, and more.

Top comments (0)