πŸ”’

Mixed Content

Security Auditor

Detects HTTP resources on HTTPS pages and CSP upgrade directive

Security
30 credits
Per check
~30 seconds
Average runtime
Active
Status

Run this auditor

3 of 3 free audits left today

See what Mixed Content finds on your site. No sign-up needed.

How it works

  1. Render β€” launches a headless Chromium as 37AuditsBot and navigates to the audited URL, waiting up to 60 s for the load event and then up to 15 s more for the network to go idle (a page that keeps polling is judged on the requests seen by then). A blocked page ends the audit with 590; no response or an HTTP status of 400 or more ends it with 500; a browser failure that survives one relaunch ends it with 501.

  2. Collect β€” records every request the browser made while loading, plus the resolved src / href of every img, script, link, iframe, video, audio and source element left in the rendered DOM. A resource counts only when its URL starts with http:// (any letter case); the audited document and its redirect hops never count. Each URL is reported once, with the place it was first seen (request or dom).

  3. Upgrade directive β€” reads Content-Security-Policy from the final response the browser rendered (after redirects); when there is no header, from a <meta http-equiv="Content-Security-Policy"> tag. The page has the safety net when one of the directives is upgrade-insecure-requests.

  4. Rules β€” every insecure resource fails (400) when the directive is absent, or warns (300) when it is present. FAIL wins over WARNING; when nothing was loaded over plain HTTP the audit is SUCCESS (200) and names the number of requests observed.

  5. Specification pin β€” every run emits 37A-MixedContentAuditor-100 (INFORMATION), naming the W3C Mixed Content (Level 2) Candidate Recommendation Draft of 2023-02-23. It does not change the overall status.

Preferences

KeyTypeDefaultDescription
evaluateExternalResourcesbooleantrueWhen false, resources served from a host other than the audited site or one of its subdomains (www. ignored) are not reported, even when they load over HTTP. Each one left out is listed as an INFORMATION check, 37A-MixedContentAuditor-101. Set it per monitored URL on the Configuration tab.

An invalid value (anything but a boolean or "true"/"false") makes the auditor fall back to the default and log a warning.

What this auditor validates

Every row maps to one checkRule* method and one CheckCode, in the order the auditor runs them. CheckCode suffixes use status ranges: 100 information, 200 success, 300–399 warning, 400–499 fail, 500–599 error.

CheckCodeStatusWhen it firesRecommendationWhy it matters
37A-MixedContentAuditor-100INFORMATIONAlways. Records the specification version this auditor implements.β€” (recommendation is null; nothing for the site to change)β€”
37A-MixedContentAuditor-400FAILOne check per resource loaded over plain HTTP while the page sends no upgrade-insecure-requests directive. The check's resource is that URL.Serve '{resource}' over HTTPS: change its URL to https:// or host a copy on a secure origin. As a stopgap, add 'upgrade-insecure-requests' to the Content-Security-Policy of {url}.Browsers block insecure scripts, styles and frames on an HTTPS page and drop the padlock when images or media load over HTTP, so parts of the page break or look untrustworthy, and anyone on the network can tamper with what is loaded.
37A-MixedContentAuditor-300WARNINGOne check per resource referenced over plain HTTP while the page's Content-Security-Policy (header or meta) carries upgrade-insecure-requests. The check's resource is that URL.Change the URL of '{resource}' to https:// in the page source so it no longer depends on the upgrade-insecure-requests directive.The directive is a safety net, not a fix: older browsers and tools that ignore it still load the resource over plain HTTP, and the upgrade silently fails when the host has no HTTPS version, so part of your visitors see a broken or "Not secure" page.
37A-MixedContentAuditor-200SUCCESSAll rules passed: no resource was loaded over plain HTTP. Message names the number of requests the browser made and whether upgrade-insecure-requests is sent.β€”β€”
37A-MixedContentAuditor-500ERRORThe browser got no response for the page, or an HTTP status of 400 or more that is not a block.Make sure {url} answers with HTTP 2xx, then run the audit again. Last error: {error}.β€”
37A-MixedContentAuditor-501ERRORPlaywright could not render the page (navigation timeout, browser crash on both launches, protocol error).Make sure {url} loads in a headless Chromium browser, then run the audit again. Last error: {error}.β€”
37A-MixedContentAuditor-590ERRORThe audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page.Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See https://www.37audits.com/bot.While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported.
37A-MixedContentAuditor-101INFORMATIONevaluateExternalResources is false: one check per external resource the page requested or referenced that was not checked, served from a host other than the audited site or one of its subdomains. The check's resource is that URL; data carries host, siteHost and evaluateExternalResources: false. Message: Not evaluated: the resource {resource} is served from {host}, outside {siteHost}, and Evaluate external resources is off. Never changes the result's status.Turn on Evaluate external resources for this monitored URL to assess third-party resources too.β€”

Output Documentation

StatusDescriptionTest logic
SUCCESSThe page loaded nothing over plain HTTPNo request and no src / href in the rendered DOM starts with http://, the audited document excluded (200).
WARNINGInsecure references exist, but browsers upgrade themOne or more insecure resources and upgrade-insecure-requests in the CSP header or meta (300, one check per resource).
FAILInsecure resources are loaded as-isOne or more insecure resources and no upgrade-insecure-requests directive (400, one check per resource).
ERRORThe auditor could not load or render the pageNo response or HTTP β‰₯ 400 (500); Playwright failure after the relaunch (501); site blocked 37AuditsBot (590).
INFORMATIONSpecification pinAlways emitted (100); does not change overall status.

Each 300 / 400 check carries resource, source (request when the browser fetched it, dom when only the rendered markup references it), hasUpgradeInsecureRequests and csp (the policy, truncated to 300 characters) in its data; the 200 check carries url, requestCount, hasUpgradeInsecureRequests and csp.

Risks and Considerations

Why mixed content matters

  • Browsers block insecure scripts, stylesheets, frames and fetches on an HTTPS page, so a single http:// script tag can take down a feature for every visitor.

  • Images, video and audio over HTTP are upgraded by current browsers and blocked when the upgrade fails; older browsers load them and drop the padlock, which visitors read as "this site is not safe".

  • A plain HTTP request can be read and rewritten on the network, so an insecure script is a remote code execution vector on your page.

upgrade-insecure-requests is a stopgap

  • The directive tells browsers to rewrite http:// requests to https:// before sending them. It hides the problem from visitors on current browsers, but the page source still points at insecure URLs, and the upgrade fails silently when the host serves no HTTPS. Fix the URLs and keep the directive as a safety net.

  • The auditor reads the directive from the response header first and from a <meta http-equiv> tag only when there is no header, like browsers combine them.

What changed in this version

  • http:// inside a query string (for example ?u=http://example.com) no longer counts: a resource is flagged only when its own URL starts with http://.

  • The audited document and its redirect hops are never flagged, even when the audited URL is itself plain HTTP.

  • The Content-Security-Policy header is read from the final response after redirects; before, it was only found when no redirect happened.

  • A page that answers HTTP 400 or more is an ERROR (500) instead of being audited as if it were the site.

  • A browser failure is an ERROR with its own code (501) instead of the raw Playwright message with no code.

  • Verdict severities are unchanged: an insecure resource still fails, and still warns when upgrade-insecure-requests is present.

What this auditor does not check

  • Only the audited URL is rendered; other pages of the site may load insecure resources.

  • Requests made after the 15 s network-idle cap, or after a user interaction, are not seen; the result message says so when the page never went idle.

  • A link element is reported whatever its rel, so an http:// canonical or alternate link shows up although browsers never fetch it.

  • Resources behind a consent banner or a login are only seen when the page loads them anyway.

This documentation is built and hosted on Mintlify, a developer documentation platform.

Source: docs.37audits.com

Ready to start auditing?

Add this auditor to your monitoring setup and start identifying issues on your websites today.

Β© 2026 37 Audits. All rights reserved. Audit your websites with confidence.

Supported by

Made with ❀️ in Floripa