The Difference Between Passive and Active Mixed Content
<script src="http://...">), CSS stylesheets (<link rel="stylesheet" href="http://...">), Web Fonts, <iframe> embeds, and XMLHttpRequest or Fetch calls. If an attacker on the local network tampers with an unencrypted stylesheet or script, they can rewrite forms, capture keystrokes, or redirect visitors to malicious destinations. Because of this high risk, all modern browsers automatically block active mixed content by default. The browser will not even attempt to download the file; it simply logs an error in the developer console and leaves your site with missing layouts, broken buttons, or failed AJAX requests.
Many modern browsers have also begun auto-upgrading passive mixed content (such as images) to HTTPS in the background. If the remote image host supports HTTPS, the browser silently rewrites the URL and fetches it safely. However, if that remote server does not have an SSL certificate configured, the image request fails completely, leaving a broken image placeholder on your layout. Relying on browser-level fallback behavior is never a reliable long-term strategy; locating and fixing the hardcoded links at the source remains essential.
A Prioritized Checklist to Locate Insecure Requests
-
Inspect the Browser Developer Tools Console first.
Opening your browser developer tools (F12orCtrl+Shift+Ion Linux and Windows,Cmd+Option+Ion macOS) and navigating to the Console tab is the fastest diagnostic step because browsers explicitly print an error or warning for every single mixed content request. Modern engines like Chromium and Gecko output a distinct message stating that a resource was loaded over an insecure connection along with the exact URL of the offending asset. This gives you the target filename and its full path immediately without guesswork. -
Filter the Network tab by protocol to catch dynamically triggered assets.
Switch to the Network tab in developer tools, ensure the "Preserve log" checkbox is enabled, and reload the page with a hard refresh (Ctrl+F5orCmd+Shift+R). Right-click the column headers in the request list, enable the Scheme or Protocol column, and look for any row showinghttpinstead ofhttpsorh2. This helps identify secondary requests initiated dynamically by tracking scripts, fonts loaded through@import, or AJAX polling that might not trigger an obvious red error in the main console view. -
Audit external CSS stylesheets for hardcoded font and background URLs.
If the console flags a font or a background pattern that does not appear in your HTML source code, the reference is almost certainly buried inside a compiled CSS file. Web designers often hardcode absolute HTTP paths inside@font-faceblocks orbackground-image: url('http://...')rules. When your HTML loads over HTTPS, the browser fetches the stylesheet, reads the CSS declaration, and triggers an unencrypted sub-request for the image or font file. -
Check for hardcoded schema links inside theme templates and static HTML.
Scan your template files—such as header, footer, and sidebar partials—for explicithttp://links inside<link>,<script>, or<img>tags. Developers often hardcode logos, favicon paths, or third-party tracking snippets during local development using plain HTTP, forgetting that production templates will execute under HTTPS. -
Inspect CMS database tables for absolute image and media URLs.
Content management systems such as WordPress store full, absolute URLs in database tables likewp_postsandwp_postmetawhen authors insert images or embedded media into articles. If your site existed on HTTP before you added an SSL certificate, every legacy blog post contains hardcodedhttp://yourdomain.com/wp-content/uploads/...links inside the database text fields. -
Audit third-party widgets, badges, and analytics scripts.
External trust seals, visitor counters, weather widgets, and ad banners provided by third parties frequently supply legacy embed codes written with explicithttp://prefixes. If the third-party provider does not support HTTPS on their asset server, you must either remove the widget entirely, host the asset locally on your own secure server, or replace the provider with a secure alternative. -
Verify CDN and reverse proxy custom origin settings.
If you route your traffic through a content delivery network or a reverse proxy like Cloudflare, check how the proxy communicates with your origin server. If your CMS generates canonical URLs based on the incoming web server port and your proxy forwards traffic to the origin on port 80 over plain HTTP, the CMS may continue generating absolute internal links usinghttp://even though the visitor connected to the proxy via HTTPS.
Resolving the Offending References
UPDATE statement on a CMS database without checking whether the platform stores configuration data as serialized PHP strings; running a basic string replacement inside serialized arrays will corrupt string length counters and break your layout or widget settings. Instead, use a specialized tool such as the WP-CLI command-line utility for WordPress, or an administrative search-and-replace plugin designed to handle serialization safely.
When updating code in theme templates or custom CSS, switch to root-relative paths or explicit HTTPS URLs. In the past, developers commonly used protocol-relative URLs (such as //example.com/image.png), which instructed the browser to match whichever protocol the parent page was using. However, modern security standards recommend using explicit https:// prefixes everywhere, even for internal staging environments, to ensure assets are always encrypted regardless of how the page was requested.
Using Server Headers to Mitigate Mixed Content
Content-Security-Policy (CSP) response header.
By adding the upgrade-insecure-requests directive to your web server configuration or application headers, you tell compliant browsers that every HTTP subresource requested by the page must be treated as if it were written as HTTPS. The browser rewrites http:// to https:// in memory prior to firing the network request.
In Nginx, you can add this directive inside your virtual host server block:
NGINX
# Instruct compliant browsers to automatically upgrade insecure subresources to HTTPS
add_header Content-Security-Policy "upgrade-insecure-requests;" always;upgrade-insecure-requests is not an absolute cure for every problem: if an external third-party domain hosting one of your scripts or images does not have an active SSL certificate on port 443, the upgraded request will fail with an SSL handshake error, and the resource will still not render. The header merely prevents the browser from downgrading your security status by refusing to send unencrypted requests over the wire.
Verification and Caching Caveats
http:// background image path.
Next, clear server-side object caches (such as Redis or Memcached) and page cache plugins. If your web application caches rendered HTML output to disk or memory, visitors will continue to receive the old HTML containing insecure links until that cache expires or is manually purged.
Finally, purge your CDN edge cache if you utilize external proxy distribution. Once both edge and local caches are empty, re-open Developer Tools, visit key landing pages—including the homepage, checkout screens, and older blog archives—and confirm that the console remains free of yellow warnings. With every subresource loading through a valid TLS handshake, the browser will display the standard clean padlock icon across all sessions.