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:
- Contact the provider to request HTTPS support
- Find an alternative provider that supports HTTPS
- Self-host the resource if possible and serve it over HTTPS
Step 6: Verify the Fix
After making changes:
- Clear browser cache
- Reload the page and check the Console for mixed content warnings
- Test in multiple browsers
- 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-requestsdirective - 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 withrel="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:
- The parent page is loaded over HTTPS
- One or more active content elements reference resources using the
http://protocol