1. Library
  2. Ssl and Tls
  3. Configuration

Updated 10 hours ago

Your page shows the padlock. It promises security. But if that HTTPS page loads a single image, script, or stylesheet over HTTP, attackers can reach through that hole and touch your users.

This is mixed content—and the padlock lies about it.

The Betrayal

Mixed content happens when an HTTPS page includes resources loaded via HTTP:

<!-- This HTTPS page has mixed content -->
<html>
<head>
    <link rel="stylesheet" href="http://example.com/style.css">  <!-- HTTP! -->
</head>
<body>
    <img src="http://example.com/image.jpg">  <!-- HTTP! -->
    <script src="http://example.com/script.js"></script>  <!-- HTTP! -->
</body>
</html>

The page URL says https://yoursite.com. Users see the padlock. They trust you. But those HTTP resources travel in plaintext across the network, visible to anyone watching, modifiable by anyone in the middle.

You built a fortress with screen doors.

Why This Breaks Everything

The padlock becomes a lie. Users see "secure" while their data travels unprotected.

Attackers get injection points. Intercept that HTTP JavaScript file, modify it, and now you're running the attacker's code with your site's permissions. They can steal credentials, redirect payments, exfiltrate data.

Privacy evaporates. HTTP requests reveal what users are viewing to every network observer between them and the server.

Functionality breaks. Modern browsers don't just warn about mixed content—they block the dangerous parts entirely. Your page loads broken.

Active vs. Passive: What Browsers Block

Browsers distinguish between two types based on damage potential:

Active mixed content can control the page:

  • JavaScript files
  • CSS stylesheets
  • Fetch and XMLHttpRequest calls
  • Iframes
  • Fonts

Browsers block active mixed content by default. The resources simply don't load. Your page breaks visibly.

Passive mixed content has limited impact:

  • Images
  • Audio and video
  • Prefetch requests

Browsers typically allow passive mixed content but show warnings. The padlock disappears or shows a warning icon. Attackers could swap your product images for offensive content, but they can't steal credentials through an image tag.

The trend is toward blocking everything. Don't rely on passive content being allowed forever.

Finding the Holes

Browser console. Open developer tools (F12), check the Console tab. Mixed content generates warnings with exact URLs of the offending resources.

Security panel. Chrome and Edge developer tools have a Security panel that lists every mixed content resource and explains what's blocked vs. warned.

Search your source. Look for http:// in your HTML and CSS. This catches hardcoded URLs but misses dynamically loaded content.

Network panel while interacting. JavaScript-loaded resources won't appear in the initial HTML. Use the page—click buttons, submit forms, navigate—while watching the Network panel for HTTP requests.

Common Culprits

Hardcoded HTTP URLs. Someone wrote <img src="http://example.com/logo.jpg"> years ago and it's still there.

Legacy database content. Old blog posts, product descriptions, and user comments created before your HTTPS migration, all containing HTTP links.

Third-party embeds. Ad networks, social widgets, analytics scripts, comment systems—any of these might inject HTTP resources.

CMS-generated URLs. Your content management system might have a configuration somewhere that's still outputting HTTP URLs.

The Fix

The solution is simple in concept: load everything over HTTPS. In practice:

Change HTTP to HTTPS. The obvious fix. http://example.com/script.js becomes https://example.com/script.js. Do this for everything you control.

Use relative URLs for your own resources. Instead of http://yourdomain.com/images/logo.png, use /images/logo.png. The browser uses whatever protocol the page loaded with.

Update your database. Search-and-replace HTTP URLs in your content. Most CMS platforms have tools or plugins for this.

Switch or drop third parties. If a third-party service doesn't support HTTPS, find one that does or remove it entirely. In 2024, any service still HTTP-only isn't serious about security.

The Confession Header

Content Security Policy offers a pragmatic escape valve:

Content-Security-Policy: upgrade-insecure-requests

This tells browsers: "I know my code is wrong. Please fix it for me by converting HTTP requests to HTTPS automatically."

It works. It's useful during migration. But understand what you're doing—you're confessing that your codebase contains insecure URLs and asking browsers to paper over the problem. It's a temporary fix while you do the real work of updating your code and content.

For stricter enforcement:

Content-Security-Policy: block-all-mixed-content

This blocks everything, including passive content that browsers would normally allow with a warning.

Third-Party Challenges

Advertising networks. The ad industry was slow to adopt HTTPS. Most major networks support it now, but check your ad code. Some older integrations still request HTTP.

Social widgets. Facebook, Twitter, LinkedIn—all provide HTTPS embed codes. Make sure you're using them, not ancient HTTP snippets from 2012.

User-generated content. If users can embed external resources, they might embed HTTP ones. You may need to filter their HTML or proxy external resources through your own HTTPS server.

CDNs. All major CDNs support HTTPS. If yours doesn't, that's a sign to switch.

HSTS Helps (Partially)

If you've deployed HSTS, browsers automatically upgrade HTTP requests to HTTPS—but only for your domain.

Your page at https://example.com tries to load http://example.com/image.jpg? HSTS upgrades it to HTTPS automatically.

But http://other-site.com/widget.js? Your HSTS policy doesn't apply to other domains. That's still mixed content.

HSTS is defense in depth, not a complete solution.

After You Fix It

Reload and check the console. No mixed content warnings should appear.

Check the Security panel. It should show no mixed content issues.

Test multiple page types. Home page, content pages, user-generated content, checkout flows, logged-in vs. logged-out states.

Test interactions. Click through the site. JavaScript-loaded content might introduce mixed content only after user actions.

Crawl the site. Automated tools can check hundreds of pages faster than you can click through them.

The Real Point

Mixed content is a trust problem. Users see the padlock and believe they're protected. If your page loads HTTP resources, that belief is false—and the deception is on you.

Every HTTP URL is a hole in your security. Find them. Fix them. Don't ship a fortress with screen doors.

Frequently Asked Questions About Mixed Content

Was this page helpful?

😔
🤨
😃