Mixed active content: scripts or styles over HTTP
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 Is This Important
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 XeoPix Detects This
Detection Logic
XeoPix 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, XeoPix 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
How To Fix
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-requestsStep 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
What We Store
Storage Level
Page Level — This issue is evaluated for each individual URL.
Database Table / Prisma Model
PageSecurityHeader
Stored Fields
| Field | Type | Description |
|---|---|---|
| httpActiveContentUrls | String? | URLs of active mixed content (scripts, iframes) |
Detection Dependencies
- The following data sources are required to evaluate this issue:
- HTML Document — The crawler checks for scripts, iframes, and other active content loaded over HTTP on HTTPS pages
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.
Unit Test
Test File
__tests__/seo-audit-checks/httpSecurityHeaders/issue-185-no-mixed-active.test.js
Purpose
This unit test validates that active mixed content (HTTP scripts, iframes, and other active resources loaded on HTTPS pages) is correctly detected, and that the check is only performed on HTTPS pages.
Tested Function
runHttpSecurityHeaders() from toggleGroups/httpSecurityHeaders.js
Issue Information
- Issue Number: 185
- Issue Code:
no_mixed_active - Toggle Group:
httpSecurityHeaders
Test Scenarios
Positive Test Cases
Scenarios where the issue should be reported:
- HTTPS page contains a
<script>tag with anhttp://source URL - HTTPS page contains an
<iframe>tag with anhttp://source URL - HTTPS page contains multiple active mixed content URLs (scripts and iframes) — all captured in
httpActiveContentUrls - HTTPS page contains both passive (
<img>) and active (<script>) mixed content — both issues are raised independently
Negative Test Cases
Scenarios where the issue should not be reported:
- All active content on the HTTPS page uses
https://URLs - The page itself is loaded over HTTP (not HTTPS) — mixed content does not apply
- Empty HTML document — no resources to check
Boundary Cases
- Multiple active mixed content URLs of different types (scripts + iframes) — all should be captured in
httpActiveContentUrls
Edge Cases
- Empty HTML string — handled gracefully without errors
- Distinguishes between passive and active mixed content on the same page — both issue codes are raised with their respective payloads
Expected Outcome
Pass
The issue is reported when an HTTPS page contains at least one active resource (e.g., <script>, <iframe>) with an http:// URL. The httpActiveContentUrls array in the issue details contains the detected URLs.
Fail
The issue is not reported when all active content uses HTTPS, when the page is HTTP, or when the HTML is empty.
Validation
The unit test verifies:
- Correct detection of active mixed content (HTTP scripts on HTTPS pages)
- Correct detection of active mixed content (HTTP iframes on HTTPS pages)
- No detection when all active content is secure
- No detection on HTTP pages (mixed content rules do not apply)
- Multiple active mixed content URLs are captured
- Empty HTML is handled without errors
- Passive and active mixed content are distinguished and reported separately
- The
httpActiveContentUrlspayload field is populated correctly
Related Production Files
toggleGroups/httpSecurityHeaders.js— contains therunHttpSecurityHeaders()function andextract()logicissueCodes.js— definesIssueCode.NO_MIXED_ACTIVEutils/mixedContent.js— providesdetectMixedContent()used to find HTTP resources and classify them as passive or active
Coverage Summary
- Covers the full active mixed content detection logic
- Tests script and iframe HTTP resource scenarios
- Tests single and multiple active resource scenarios
- Verifies that HTTP pages are exempt from mixed content checks
- Validates payload structure (
httpActiveContentUrls) - Tests cross-issue interaction with passive mixed content (Issue 2)
- Includes empty HTML edge case
References
- What is Mixed Content? — MDN Web Docs
- Mixed Content - Web Security — web.dev (Google)
- Content Security Policy: upgrade-insecure-requests — MDN Web Docs