SSL Toolkit Logo

Mixed Content Checker

Find insecure http:// resources on an HTTPS page

If you omit the scheme, HTTPS is assumed.

What is mixed content?

A page delivered over HTTPS is mixed when it still loads some resources over plain HTTP. The padlock disappears and the connection is only partially protected: an attacker on the network can read or modify the insecure resources even though the page itself is encrypted. Browsers treat the two kinds differently. Active mixed content - scripts, iframes, objects, stylesheets and form targets - is blocked outright, so the page usually breaks. Passive mixed content - images, audio, video, fonts and icons - is auto-upgraded to HTTPS where possible, and otherwise loads with a warning; it still leaks requests and marks the page as not fully secure.

How to fix mixed content

  1. Rewrite the offending URLs to https:// - most CDNs and APIs support HTTPS.
  2. Better still, use protocol-relative or root-relative URLs (or just //host/path) so the page's own scheme is inherited.
  3. Serve first-party assets from your own HTTPS origin instead of an HTTP host.
  4. Deploy a Content-Security-Policy with upgrade-insecure-requests to rewrite remaining HTTP URLs automatically.
  5. Add Strict-Transport-Security so browsers never fall back to HTTP.

About the Mixed Content Checker

Mixed content is the single most common reason a site that is correctly configured over HTTPS still fails to get the padlock, and the cause is almost always a hardcoded http:// in a template, an inline style or a third-party widget. Finding those by hand means opening the browser console on every page, and the console only tells you about the page you happen to be looking at.

This tool fetches a page the way a browser would, then walks the returned HTML and reports every reference that would still travel over plain HTTP. It separates the references that browsers block outright from the ones they merely warn about, because those two groups need different fixes and different urgency. Duplicate references are collapsed, and results are capped so a single broken page cannot produce an unreadable list.

How to Use

  1. Enter the full URL of the page to check, including https://. A pasted URL with a path is fine and is scanned as-is.
  2. Run the check. The page is fetched once, redirects are followed, and the final URL is what gets analysed — so a redirect from HTTP to HTTPS is visible rather than silently hidden.
  3. Read the two lists. Active findings break the page outright; passive findings leak requests and downgrade the security indicator.
  4. Fix each URL at its source: the template, the stylesheet, or the third-party widget. Editing the rendered page fixes nothing, because the next deploy reintroduces it.
  5. Re-run the check after each deploy. Fixing one reference often reveals another that was previously only visible on a route you had not visited.

Use Cases

  • Post-migration audit: confirm nothing was missed after moving a site to HTTPS.
  • Broken padlock: find the one legacy script that still loads over HTTP.
  • Third-party embeds: check that analytics, chat widgets and fonts all use HTTPS.
  • Pre-launch checks: verify a new page before it goes live.

Frequently Asked Questions

A valid certificate only secures the page itself. If the page pulls any resource over http://, the browser downgrades the connection's security indicator, and blocked active content can break the layout entirely.
Yes, though less severely than scripts. Modern browsers auto-upgrade most passive content, but older browsers will show a warning and the request still travels in the clear. Treat it as a bug to fix, not a non-issue.
It analyses the delivered HTML, so URLs constructed at runtime by scripts are not visible. For a complete picture, also open your browser's DevTools console - it reports blocked mixed content explicitly.
Active content is anything that executes or navigates: scripts, frames, objects, forms and stylesheets. Browsers block these outright, so the feature silently disappears. Passive content is images, audio, video, fonts and icons; browsers upgrade or warn, but the request can still travel over plain HTTP, revealing that a visitor is on your page and leaving the page marked as not fully secure. This tool reports both separately because the consequences are different.
Search your source and your templates rather than one page at a time. In a shell, grep -rn "http://" --include="*.html" --include="*.css" --include="*.js" . finds candidates; grep -rn "http://" --include="*.go" --include="*.py" . catches hardcoded strings in application code. The biggest offenders are usually inline styles, CSS @import rules and third-party widgets, not your templates.
No, and it is worth being precise: CSP governs what the browser is permitted to load, while mixed content is decided before CSP is consulted. A CSP with upgrade-insecure-requests does help, because it rewrites insecure URLs to HTTPS before the request is made, but it cannot rescue a host that does not offer HTTPS at all. Fix the references first, then add the directive as a safety net.
Because image loading is passive, so browsers upgrade it to HTTPS where possible and merely warn when it cannot. Blocking started as the default for scripts and frames and was deliberately relaxed for images so that a single mixed asset would not break an otherwise working page. The cost is a leaked request and a downgraded security indicator. If you see one, the asset host has no HTTPS endpoint — fix the host rather than suppressing the warning.
Usually minutes, because most of it is a handful of hardcoded URLs. Replace the references with protocol-relative or root-relative paths so the scheme follows the page, then reload with the console open and watch for remaining violations — the browser names the exact file and line. Re-scan after each deploy, since a template edit reintroduces the same reference instantly. What takes longer is the third-party widget you do not control; those need an HTTPS endpoint or removal.

Technical Details

Blockable (active) content

  • <script src>, <iframe src>, <object data>, <embed src>, <form action>
  • <link rel="stylesheet"> and CSS @import
  • fetch()/XHR and WebSocket calls to an http:// origin
  • Browsers block these outright, so the feature silently disappears

Auto-upgraded (passive) content

  • img, audio, video (src and poster), source, track, input
  • background on body, table and td
  • Icons and manifests: icon, apple-touch-icon, mask-icon, manifest
  • Hints: preload, prefetch, preconnect, dns-prefetch

What is inspected

  • src, href, poster, data, action and background attributes
  • Every candidate inside a srcset on img and source
  • url(http://...) inside style attributes and <style> blocks
  • Protocol-relative //host/file URLs, resolved against the page

Limits

  • Static HTML only: resources injected by JavaScript at runtime are not seen
  • Imported stylesheets are reported but never fetched
  • Capped at 200 findings; a larger page is flagged as truncated
  • Nothing is modified or rewritten, the report is advisory

Tips & Best Practices

  • •Fix blocked (active) findings first - those are the ones that break the page.
  • •Search your templates and CSS for the literal string http:// after each migration.
  • •Add the CSP directive upgrade-insecure-requests as a safety net.
  • •Re-scan after each deploy - a single pasted snippet can reintroduce mixed content.