Back to articles
Web Security
Updated Jun 2, 2026

Fixing Mixed Content on HTTPS Pages: How to Find and Patch Every Last One

You've successfully migrated your website to HTTPS, a crucial step for security, SEO, and user trust. But then you see it: a broken image, a missing stylesheet, or worse, a browser warning like "Your connection is not fully secure." If this sounds familiar, you're likely battling mixed content.

Mixed content occurs when a webpage loaded over secure HTTPS attempts to load some resources (images, scripts, CSS, iframes) over insecure HTTP. It's frustrating for users and, more importantly, it creates security vulnerabilities that can compromise your entire site.

This guide is your comprehensive roadmap to identifying, understanding, and eliminating mixed content. We'll walk you through step-by-step solutions, from quick code fixes to advanced server-side strategies, ensuring your HTTPS site works perfectly and stays secure.

Table of Contents

Understanding Mixed Content: Why It's a Problem

Mixed content isn't just an aesthetic annoyance, it's a real security risk. The HTTPS lock on a page only protects the resources that came in over HTTPS. The moment the page also pulls in an HTTP script or image, that resource is travelling in the clear, and an attacker on the network can intercept and modify it in transit. In practical terms that means injecting a malicious script into your otherwise-secure page, or swapping a logo for a phishing image. The padlock lies to the user; the page is no longer trustworthy end to end.

There's also a trust and UX cost on top of the technical one. Browsers downgrade the padlock, warn the user, or refuse to render the resource entirely. So even when nothing gets actively exploited, you lose conversions to the warning bar, and you lose functionality because modern browsers block "active" mixed content (scripts, stylesheets, iframes) outright to protect users. A single hardcoded http:// URL in a third-party widget can quietly break checkout in production.

Types of Mixed Content

Browsers split mixed content into two buckets based on how much damage the resource can do. Active mixed content covers anything that can change the page or run code in its context: <script>, <link rel="stylesheet">, <iframe>, XMLHttpRequest and fetch calls, and <object> tags. Browsers block these by default, no prompt. Passive mixed content covers resources that can't reach into the page's JS context: <img>, <audio>, <video>, and <source> elements. Those typically still load, but the browser strips the secure padlock and logs a warning. Treat both seriously; passive content is what attackers replace with phishing imagery when they want the user, not the script engine.

Your First Line of Defense: Identifying Mixed Content

You can't fix what you can't find. Here's how to pinpoint mixed content issues.

1. Browser Developer Tools (Your Best Friend)

DevTools is the fastest way to find mixed content on a single page. Open it with F12 on Windows or Linux, Cmd + Option + I on macOS, or right-click and pick "Inspect." In the Console tab you'll see explicit messages along the lines of Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure resource 'http://example.com/image.jpg'. This request has been blocked/warned. Reload with the Network tab open and you can filter by blocked requests (or by CSP-blocked if you've set one up) to surface every insecure URL the page tried to fetch.

2. Automated Detection Tools

For larger sites, manual checks are insufficient. Hosted scanners like WhyNoPadlock.com and the SSL Labs SSL Test crawl a page and report mixed-content findings, which is convenient when you don't have the site checked out locally. If you do have it locally, a one-liner is often enough to spot obvious offenders:

# Quickly grep for HTTP links in a webpage's source
curl -s https://your-site.com | grep -i "http://"

3. Codebase Analysis (Search & Replace)

For hardcoded references it's hard to beat a brute-force grep across the repo:

# Search in HTML, CSS, and JavaScript files
grep -r "http://" your_project_directory/

Pay extra attention to URLs inside <img src="...">, <script src="...">, <link href="...">, @import url(...) in CSS, and fetch('http://...') in JavaScript. Those are where the false positives are lowest and the real bugs hide.

Common Sources of Mixed Content (And Where to Look)

Mixed content tends to enter from a small number of predictable places. Developers hardcode http:// URLs into templates and code; old CMS posts and database rows still carry http:// from before the migration; third-party widgets, analytics snippets, social buttons, and ad tags ship insecure script URLs; and user-generated comments and forum posts keep importing http:// links forever. CSS is its own little trap, with background images and webfonts referenced via url(http://...), and JavaScript adds dynamically loaded scripts plus AJAX endpoints that point at an HTTP backend. If you only have time to check three places, check the template layer, the CMS database, and the third-party tags in the page head.

Comprehensive Fix Strategies: Eradicating Mixed Content

Once you've identified the source, here's how to eliminate mixed content.

1. The Golden Rule: Use HTTPS Directly

The best and most permanent fix is the boring one: rewrite every http:// URL to https://. In HTML, CSS, and JavaScript that means a manual pass (or a scripted one) over internal and external resources wherever HTTPS is actually supported. For a CMS, do it in the database with search-and-replace tools or plain SQL:

-- WordPress Example: Update all HTTP URLs to HTTPS in post content
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://yourdomain.com', 'https://yourdomain.com');
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://www.yourdomain.com', 'https://www.yourdomain.com');
-- Repeat for other relevant tables like wp_postmeta, wp_options

For third-party services, always pull the HTTPS version of the script or asset. If a vendor still doesn't serve over HTTPS in the current decade, that's a signal to replace them.

2. Protocol-Relative URLs (Use with Caution)

Protocol-relative URLs like //example.com/image.jpg reuse whatever protocol the page is on. On HTTPS the resource loads over HTTPS; on HTTP it loads over HTTP. That sounds clever, but it doesn't force HTTPS, it just inherits whatever the current page happens to use. The moment something causes a page to be served over HTTP again (a misconfigured redirect, a staging environment, a captive portal), every subresource silently falls back to insecure. Prefer explicit https:// and skip this pattern unless you have a specific reason.

3. Content Security Policy (CSP) with upgrade-insecure-requests

The upgrade-insecure-requests CSP directive tells the browser to rewrite any http:// subresource request to https:// before sending it. If the resource isn't available over HTTPS, it simply fails to load. That's exactly the behaviour you want during a cleanup, and it's also the cleanest mitigation for third-party content you can't directly edit.

Content-Security-Policy: upgrade-insecure-requests;

You can ship it from the web server, the CDN, or the application layer. An Nginx example:

# Nginx Example: Add CSP header
add_header Content-Security-Policy "upgrade-insecure-requests;" always;

For the bigger picture on CSP, see our Content Security Policy Guide.

4. Server-Side URL Rewriting

When the offending URL is baked into content you can't easily edit (an old CMS, vendor markup, cached HTML), let the web server rewrite it on the way out. Nginx's sub_filter is handy for this:

# Nginx Example: Proxy rewrite for specific HTTP content
location / {
    sub_filter 'http://cdn.old-domain.com' 'https://cdn.old-domain.com';
    sub_filter_once off; # Apply to all occurrences
    # ... other configurations
}

5. CDN and Edge Solutions

Most CDNs ship a one-click switch for this. On Cloudflare it's "Automatic HTTPS Rewrites." On AWS CloudFront, set the "Viewer Protocol Policy" to "Redirect HTTP to HTTPS" and reach for Lambda@Edge if you need to rewrite specific subresource URLs. Azure Front Door does the same job through routing rules that enforce HTTPS and can rewrite outbound URLs. None of these replace fixing the root cause in your codebase, but they're a solid safety net while you do.

6. Application-Level JavaScript Rewriting (Last Resort)

A client-side rewrite is the worst option because it runs after the initial parse, so the browser may already have logged the warning or blocked the request. Use it only when server-side rewrites and CSP aren't available:

// Example: Upgrade all http:// image sources to https://
document.addEventListener("DOMContentLoaded", () => {
  document.querySelectorAll('img[src^="http://"]').forEach((img) => {
    img.src = img.src.replace("http://", "https://")
  })
})

Continuous Monitoring & Prevention

Fixing mixed content is an ongoing effort, especially with dynamic sites and user-generated content.

1. Automated Checks in CI/CD

The cheapest way to keep this fixed is to fail the build the first time it regresses. A short Playwright test that watches the console for "Mixed Content" warnings is enough to catch most cases before they ship:

// Example: Playwright test to fail build on mixed content warnings
import { chromium } from "playwright"
test("should not have mixed content warnings", async ({ page }) => {
  const mixedContentErrors = []
  page.on("console", (msg) => {
    if (msg.type() === "warning" && msg.text().includes("Mixed Content")) {
      mixedContentErrors.push(msg.text())
    }
  })
  await page.goto("https://your-site.com") // Test your actual URL
  await page.waitForLoadState("networkidle")
  expect(mixedContentErrors).toHaveLength(0) // Fails if any mixed content is found
})

2. Regular Scanning

CI catches what your engineers ship. It doesn't catch what a marketer pastes into the CMS at 4pm on a Friday. For that you want a scheduled scan that checks the rendered pages from the outside. Barrion's dashboard runs continuous scans for mixed content alongside the rest of your web security posture and alerts you when something new shows up, and it's worth re-running a general online mixed-content scanner against your top pages on a cadence as well.

3. Developer Awareness

The cheapest fix is the one you don't have to make. Tell the team: use https:// for every external resource, use relative paths for internal assets, and treat a hardcoded http:// URL in a PR the way you'd treat a hardcoded password. Once that becomes a code-review reflex, the long tail of new mixed-content bugs goes away on its own.

Conclusion: A Fully Secure HTTPS Experience

Mixed content is a familiar headache, but it's a solvable one once you stop chasing individual warnings and approach it as a process. Find the sources with DevTools and a recursive grep over the repo. Convert hardcoded http:// URLs to https:// everywhere they live, including the database, not just the templates. Layer upgrade-insecure-requests on top as a safety net for content you don't control. Then automate the check so you don't have to remember to look. Do those four things and you stop putting out fires; the padlock stays green, the warnings stay quiet, and your users get the secure experience you've already paid for.


Ready to Clean Up Your Website?

Start your free security scan with Barrion today to get immediate insights into any mixed content issues and other vulnerabilities on your site.

For detailed analysis and continuous monitoring of your web application security, visit the Barrion dashboard.

Frequently asked questions

Q: Why does mixed content appear after enabling HTTPS?

A: Legacy "http://" references in templates, CSS, or third-party embeds often remain after the HTTPS cutover. Update these to HTTPS or update to modern packages.

Q: Is upgrade-insecure-requests a permanent fix?

A: No. It's a temporary bridge. Fix the sources to avoid surprises and maintain long-term security.

Q: Can my CDN fix mixed content for me?

A: CDN rewrites can help, but aim to correct code and content. Use rewrites only as a safety net.

Secure your apps before
someone else finds the gaps.

Trusted by dev teams and agencies for security monitoring and audit-ready reports.