No Mixed Content (HTTP Assets on HTTPS Pages)
Issue No: 2
Category: HTTP Security Headers
Issue type: Issue
Priority: CRITICAL
Description
This audit verifies that pages served over HTTPS do not request or load subresources (such as images, scripts, stylesheets, iframes, or media) over insecure HTTP connections, preventing mixed content vulnerabilities and browser-level blocking.
How do we capture it
- Initial Scheme Evaluation: Inspect the requested page URL. If the scheme is not https://, skip this audit immediately.
- Retrieve Raw HTML: Fetch the page's raw HTML response via an HTTP GET request.
- Parse HTML Elements: Parse the static, server-side rendered (SSR) HTML payload. Target the following elements and attributes known to trigger subresource loading:
srcattribute from<img>,<script>,<iframe>,<video>,<audio>,<source>,<embed>hrefattribute from<link rel="stylesheet">,<link rel="import">dataattribute from<object>
- Filter and Normalize URLs:
- Ignore relative URLs (e.g.,
/style.css,../images/pic.png) as they inherit the secure page scheme automatically. - Ignore protocol-relative URLs (e.g.,
//cdn.example.com/lib.js) since they resolve to the secure scheme of the parent document. - Select only absolute URLs that explicitly begin with the insecure
http://protocol.
- Ignore relative URLs (e.g.,
- Inspect Security Headers & Meta Tags: Scan the HTTP response headers and
<meta>tags for the presence of a Content Security Policy (CSP) directive containingupgrade-insecure-requests. - Error and Timeout Handling: If the HTML parser encounters broken syntax, parse using robust, fault-tolerant HTML reading libraries. If the crawler connection times out, record the failure as a crawler-level issue and do not flag false-positive mixed content warnings.
Constraint Note: The crawler executes static analysis only. It does not run a JavaScript rendering engine or evaluate the DOM post-load. Dynamic mixed content introduced by client-side scripting or post-load DOM insertion cannot be detected by this crawler script. Assume that the site uses server-side rendering (SSR).
What to store
| Field | Type | Comment |
|---|---|---|
is_https | BOOLEAN | Indicates if the main page URL is served over a secure HTTPS protocol. |
mixed_content_detected | BOOLEAN | Set to true if one or more subresources are requested via HTTP on an HTTPS page. |
insecure_resource_count | INTEGER | The total number of insecure HTTP subresource URLs discovered. |
insecure_resources_list | TEXT | A JSON-serialized array of objects specifying each insecure resource's tag name, attribute, and target HTTP URL. |
has_upgrade_insecure_requests | BOOLEAN | Set to true if the response headers or <meta> tags declare a CSP upgrade-insecure-requests instruction. |
Condition for trigger
The following rules determine when a mixed content violation should be triggered on scanned HTTPS documents:
- Trigger Rule 1: Insecure Active or Passive Subresources Found
- Target Field:
mixed_content_detected - Evaluation Logic:
= TRUE - Severity: CRITICAL
- Diagnostic Message: "Page is served over HTTPS but requests insecure resources over HTTP, creating a mixed content vulnerability."
- Target Field:
Sources
- W3C Mixed Content Specification: https://www.w3.org/TR/mixed-content/
- MDN Web Docs - Mixed Content: https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
- Google Search Central - Secure your site with HTTPS: https://developers.google.com/search/docs/crawling-indexing/https-migration
Long description
Mixed content occurs when initial HTML is loaded over a secure HTTPS connection, but subresources (such as images, videos, stylesheets, and scripts) are loaded over insecure HTTP connections. This compromises the integrity of the secure page, opening up paths for active and passive network eavesdropping.
Modern web browsers classify mixed content into two categories:
- Passive Mixed Content: Content that does not interact with the DOM (e.g.,
<img>,<audio>,<video>). Browsers may load these but will degrade the security indicator in the address bar, warning the user that the site is not fully secure. - Active Mixed Content: Content that can access and alter the DOM (e.g.,
<script>,<iframe>,<link rel="stylesheet">,<object>). Modern browsers block active mixed content entirely by default to prevent cross-site scripting (XSS) and Man-In-The-Middle (MITM) attacks.
Common crawler failure scenarios:
- Absolute, legacy URLs referencing images hosted on third-party domains using explicit
http://protocols. - Hardcoded script tags referencing tracking scripts or external libraries without specifying HTTPS.
- Insecure CSS resource imports where fonts or background images are requested over raw HTTP.
How to Fix
- Audit Source Templates: Review your source code templates, content management systems, and database entries for any hardcoded
http://links pointing to assets. - Convert to Secure or Relative Links: Update insecure absolute URLs to use relative paths (
/assets/script.js), protocol-relative paths (//example.com/script.js), or explicitly securehttps://URLs. - Verify Host Support: Ensure all external domains, CDNs, and third-party API providers hosting your assets have valid SSL/TLS certificates and support secure HTTPS requests.
- Deploy Upgrade Policy: Configure your web server to return a Content Security Policy (CSP) header, or add a meta tag in the HTML
<head>, containing theupgrade-insecure-requestsdirective. This instructs compliant browsers to automatically upgrade insecure HTTP requests to HTTPS before attempting to fetch them.