Skip to content
Browse all guides

Issue #185 · critical

Issue 185

What is this issue?

Mixed Content (Active Content Over HTTP)

This issue detects when a webpage loaded over HTTPS (secure connection) also loads active content such as scripts, iframes, or other executable resources over HTTP (insecure connection).

What Passes

A page passes this check when:

  • All active content (scripts, iframes, etc.) is loaded over HTTPS
  • No insecure HTTP resources are loaded on an HTTPS page
  • The page uses protocol-relative URLs (//example.com/script.js) that inherit the parent page's protocol

What Fails

A page fails this check when:

  • A script tag loads JavaScript from an http:// URL on an HTTPS page
  • An iframe loads content from an http:// URL on an HTTPS page
  • Other active content (like Flash objects or Java applets) loads over HTTP on an HTTPS page

Real-World Example

Failing Example:

<!-- Page loaded over HTTPS -->
<script src="http://cdn.example.com/jquery.js"></script>
<iframe src="http://maps.example.com/widget"></iframe>

Passing Example:

<!-- Page loaded over HTTPS -->
<script src="https://cdn.example.com/jquery.js"></script>
<iframe src="https://maps.example.com/widget"></iframe>
<!-- Or use protocol-relative URLs -->
<script src="//cdn.example.com/jquery.js"></script>

Why does it matter?

Security Impact

1. Compromised HTTPS Security

When a page loads active content over HTTP, it undermines the security benefits of HTTPS:

  • Man-in-the-Middle Attacks: Attackers can intercept and modify HTTP resources
  • Script Injection: Insecure scripts can be replaced with malicious code
  • Data Theft: Sensitive information can be captured from insecure requests

2. Browser Warnings and Blocking

Modern browsers handle mixed content aggressively:

  • Warnings: Browsers display security warnings to users
  • Blocking: Many browsers block mixed active content entirely
  • User Trust: Security warnings reduce user confidence and increase bounce rates

SEO Impact

1. User Experience and Engagement

  • Broken Functionality: Blocked scripts can break core page functionality
  • Poor User Experience: Security warnings create friction and distrust
  • Increased Bounce Rates: Users leave when they see security warnings

2. Page Performance

  • Blocking Issues: Browsers may block mixed content, causing functionality failures
  • Inconsistent Behavior: Different browsers handle mixed content differently

3. Search Engine Rankings

While not a direct ranking factor, mixed content indirectly affects SEO by:

  • Reducing user engagement signals (time on site, pages per session)
  • Increasing bounce rates
  • Potentially affecting Core Web Vitals if scripts are blocked

Impact on SEO Health Score

Resolving mixed content issues improves the overall SEO health score by:

  • Ensuring full HTTPS implementation
  • Eliminating browser security warnings
  • Ensuring all page functionality works correctly
  • Improving user trust and engagement metrics

A site with mixed content signals incomplete security implementation and can negatively impact both user experience and search engine trust.

How to fix it

Step 1: Identify All Mixed Content

Use browser developer tools or automated scanners to find all HTTP resources loaded on HTTPS pages:

  • Open Chrome DevTools → Console tab (mixed content warnings appear here)
  • Use the Network tab to filter for non-secure requests
  • Run an automated HTTPS audit

Step 2: Update Resource URLs to HTTPS

For each insecure resource, update the URL to use HTTPS:

Before:

<script src="http://cdn.example.com/library.js"></script>
<img src="http://images.example.com/photo.jpg" />
<iframe src="http://widgets.example.com/form"></iframe>

After:

<script src="https://cdn.example.com/library.js"></script>
<img src="https://images.example.com/photo.jpg" />
<iframe src="https://widgets.example.com/form"></iframe>

Step 3: Use Protocol-Relative URLs (Optional)

If the resource is available on both HTTP and HTTPS, use protocol-relative URLs:

<!-- This inherits the parent page's protocol -->
<script src="//cdn.example.com/library.js"></script>
<img src="//images.example.com/photo.jpg" />

Note: Protocol-relative URLs are becoming less common. Using explicit https:// is now the recommended approach.

Step 4: Use Content Security Policy (CSP)

Implement a Content Security Policy to automatically upgrade insecure requests:

<!-- Upgrade all insecure requests to HTTPS -->
<meta
  http-equiv="Content-Security-Policy"
  content="upgrade-insecure-requests"
/>

Or via HTTP header:

Content-Security-Policy: upgrade-insecure-requests

Step 5: Check Third-Party Resources

For third-party resources that don't support HTTPS:

  1. Contact the provider to request HTTPS support
  2. Find an alternative provider that supports HTTPS
  3. Self-host the resource if possible and serve it over HTTPS

Step 6: Verify the Fix

After making changes:

  1. Clear browser cache
  2. Reload the page and check the Console for mixed content warnings
  3. Test in multiple browsers
  4. Use automated tools to scan for remaining mixed content

Prevention

To prevent mixed content issues in the future:

  • Always use https:// URLs for all resources
  • Implement CSP upgrade-insecure-requests directive
  • Use relative URLs without protocol when possible (e.g., /path/to/resource)
  • Set up automated mixed content monitoring

Examples

Example 1: Mixed Content in Script Tags

Problematic State (Fails)

<!-- Page loaded over HTTPS -->
<!DOCTYPE html>
<html>
  <head>
    <title>My Secure Page</title>
  </head>
  <body>
    <h1>Welcome</h1>
    <!-- This script is loaded over insecure HTTP -->
    <script src="http://cdn.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
      // This code may not execute if the browser blocks the insecure script
      $(document).ready(function () {
        console.log("Page loaded");
      });
    </script>
  </body>
</html>

Issue: The jQuery library is loaded over HTTP on an HTTPS page. Modern browsers will block this or show a warning.

Corrected State (Passes)

<!-- Page loaded over HTTPS -->
<!DOCTYPE html>
<html>
  <head>
    <title>My Secure Page</title>
  </head>
  <body>
    <h1>Welcome</h1>
    <!-- Script now loaded over HTTPS -->
    <script src="https://cdn.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
      $(document).ready(function () {
        console.log("Page loaded");
      });
    </script>
  </body>
</html>

Fix: Updated the script URL to use https:// instead of http://.


Example 2: Mixed Content in iframes

Problematic State (Fails)

<!-- Page loaded over HTTPS -->
<iframe src="http://maps.google.com/maps?q=New+York"></iframe>

Issue: The iframe loads a map over HTTP, which browsers may block or flag as insecure.

Corrected State (Passes)

<!-- Page loaded over HTTPS -->
<iframe src="https://maps.google.com/maps?q=New+York"></iframe>

Fix: Updated the iframe URL to use https://.


Example 3: Protocol-Relative URLs (Acceptable Solution)

Problematic State (Fails)

<!-- Page loaded over HTTPS -->
<link rel="stylesheet" href="http://cdn.example.com/bootstrap.css" />

Issue: The stylesheet is loaded over HTTP.

Corrected State (Passes - Protocol-Relative)

<!-- Page loaded over HTTPS -->
<link rel="stylesheet" href="//cdn.example.com/bootstrap.css" />

Fix: Removed the protocol (http:) so the URL inherits the parent page's protocol (https:).

Note: While this works, using explicit https:// is now the recommended approach:

<link rel="stylesheet" href="https://cdn.example.com/bootstrap.css" />

Example 4: Third-Party Widget

Problematic State (Fails)

<!-- Page loaded over HTTPS -->
<div class="payment-form">
  <!-- Payment widget loaded over HTTP -->
  <iframe src="http://payment-gateway.example.com/widget"></iframe>
</div>

Issue: The payment widget is loaded over HTTP, which is a security risk for financial transactions.

Corrected State (Passes)

<!-- Page loaded over HTTPS -->
<div class="payment-form">
  <!-- Payment widget now loaded over HTTPS -->
  <iframe src="https://payment-gateway.example.com/widget"></iframe>
</div>

Fix: Updated the payment widget URL to use https://. If the third-party provider doesn't support HTTPS, you should switch to a provider that does.

How PixyScan detects this

Detection Logic

PixyScan identifies mixed content issues through the following process:

Step 1: Verify the Page is Loaded Over HTTPS

The crawler first confirms that the parent page is loaded over a secure HTTPS connection. Mixed content is only an issue when the parent page uses HTTPS.

Step 2: Parse the HTML Document

The crawler parses the HTML document and extracts all elements that can load active content, including:

  • <script> tags (src attribute)
  • <iframe> tags (src attribute)
  • <object> tags (data attribute)
  • <embed> tags (src attribute)
  • <link> tags with rel="stylesheet" (href attribute)

Step 3: Check Resource URLs

For each detected element, the crawler examines the resource URL:

  • If the URL starts with http:// (explicit HTTP), it is flagged as mixed content
  • If the URL starts with https:// (explicit HTTPS), it is considered secure
  • If the URL is protocol-relative (starts with //), it inherits the parent page's protocol and is not flagged
  • If the URL is relative (starts with / or doesn't include a protocol), it inherits the parent page's protocol and is not flagged

Step 4: Record Mixed Content URLs

When mixed content is detected, PixyScan records:

  • The URLs of all insecure resources found on the page
  • These URLs are stored for reporting and analysis

Step 5: Determine Pass/Fail

The page fails this check if:

  • At least one active content resource is loaded over HTTP on an HTTPS page

The page passes this check if:

  • The page is loaded over HTTP (mixed content doesn't apply)
  • The page is loaded over HTTPS and all active content resources use HTTPS or protocol-relative URLs

What is Checked

  • Script tags: JavaScript files loaded via <script src="...">
  • Iframes: Embedded content loaded via <iframe src="...">
  • Object/Embed tags: Legacy plugin content (Flash, Java applets)
  • Stylesheet links: CSS files loaded via <link rel="stylesheet" href="...">

What is Not Checked

  • Passive content: Images (<img>), audio (<audio>), video (<video>) are considered passive content and may trigger warnings but are less critical than active content
  • CSS background images: These are loaded by the browser and may not be detected in initial HTML parsing
  • Dynamically loaded content: Content added via JavaScript after page load may not be detected

Conditions for Failure

The issue is flagged when:

  1. The parent page is loaded over HTTPS
  2. One or more active content elements reference resources using the http:// protocol

References