Guide : Mixed Content

Ce que mixed content is, pourquoi active mixed content obtient blocked pendant que passive obtient warned à propos de, and how to detect and fix insecure sub-resources at scale — le navigateur console, CSP reporting, upgrade-insecure-requests, block-all-mixed-content, and how CMSes and ad tech reintroduce it.

Première publication : 3 juil. 2026 · Dernière mise à jour : 3 août 2026 · Advanced
Langues

Mixed content is an HTTPS page chargement a sub-resource over HTTP. Navigateurs' current taxonomy is upgradable versus blockable; the older active/passive split encore tracks que pour la plupart types, with exceptions (CORS-enabled images, srcset/picture, and IP-host requêtes are blockable, pas upgradable). Active mixed content — scripts, stylesheets, iframes, XMLHttpRequest/récupérer — is blocked outright parce que a tampered script peut rewrite the whole page, so it's ce que en réalité breaks a site après an HTTP→HTTPS migration; fix it premier. Passive mixed content — images, audio, video — historically chargé with a downgraded padlock and is now increasingly auto-upgraded or blocked aussi. Anchor liens and autre top-level HTTP navigation ne sont pas mixed content, and neither are insecure downloads (a connexe, separate boundary). Trouver it à travers récupéré source, rendered/runtime state, and real-user sessions: explorer the HTTPS site, watch the Chrome DevTools console (exact wording is navigateur/version spécifique), or collect Content-Security-Policy-Report-Only violations; fix it by premier confirming the HTTPS equivalent en réalité fonctionne, alors pointing every sub-resource at https:// (relative/protocol-relative paths seulement après verifying ownership and base-URL behavior). Le contenu-Security-Policy: upgrade-insecure-requests header rewrites in-scope http:// sub-resource requêtes — notamment cross-origin ones — to https:// avant they're sent and avant mixed-content/CSP checks run; it has aucun HTTP fallback si the upgrade fails, it's a safety net plutôt que a substitute pour cleaning the source, it ne fait pas upgrade top-level navigation to third-party origins (so it isn't a replacement pour HSTS), and setting the directive itself in report-only mode is a no-op — monitor with a separate report-only policy à la place. CMS databases (back up and dry-run replacements — naive string-replace peut corrupt serialized données), plugins/themes, service workers/caches, and ad/analytics tags are the usual re-offenders; audit at scale with a robot d’exploration and CSP reporting plutôt que page by page.

TL;DR — Mixed content is an HTTPS page chargement a sub-resource over HTTP. The current navigateur/W3C taxonomy sorts ce into upgradable and blockable content; the older active/passive split (utilisé ci-dessous as a blast-radius framing) encore tracks que divide pour la plupart resource types, with exceptions — CORS-enabled images, srcset/picture candidates, and IP-host requêtes are blockable même though a plain img src is upgradable. Active (scripts, stylesheets, iframes, XMLHttpRequest/fetch, and anything le navigateur executes) is blocked — a tampered script peut rewrite lune page — so it’s the launch-day regression to fix premier. Passive (images, audio, video) historically chargé with a downgraded indicator and is now increasingly auto-upgraded or blocked. Anchor liens and autre top-level HTTP navigation aren’t mixed content; neither are insecure downloads, qui are a connexe but separate boundary. Detect it à travers three layers — récupéré source, rendered/runtime state, and réel utilisateur sessions — by exploration the HTTPS site, reading the Chrome DevTools console (exact wording is navigateur/version spécifique), or collecting Content-Security-Policy-Report-Only violations; fix it by confirming an HTTPS equivalent en réalité fonctionne, alors pointing every sub-resource at https:// (relative/protocol-relative paths are fine une fois you’ve verified ownership and base-URL behavior, pas a universal par défaut). Content-Security-Policy: upgrade-insecure-requests rewrites in-scope http:// sub-resource requêtes (notamment cross-origin ones) to https:// avant they’re sent and avant mixed-content/CSP checks run — a net, pas a substitute pour fixing the source, with aucun HTTP fallback si the upgrade fails, and it fait pas upgrade top-level navigation to third-party origins, so it doesn’t replace HSTS. Putting the directive itself in report-only mode is a no-op — monitor with a separate report-only policy à la place. CMS databases (back up and dry-run quelconque replacement — naive string-replace peut corrupt serialized données), plugins, themes, service workers/caches, and ad/analytics tags are the recurring re-offenders — audit at scale, pas page by page.

The HTTPS hub introduces mixed content as un of the two launch-day échec modes of a migration (the autre being redirections). Ce is the deep dive it points to — the exact resource tiers, the detection stack, the CSP directives, and the operational raisons it garde coming back.

Ce que counts as mixed content — and ce que doesn’t

Mixed content is scoped precisely: it’s à propos de sub-resources lune page loads, pas à propos de liens lune page contient. Google’s definition: “Une page has mixed content quand its initial HTML is chargé over a secure HTTPS connection, but autre resources (tel as images, videos, stylesheets, and scripts) are chargé over an insecure HTTP connection.” Evidence for this claim Mixed content occurs when a secure page loads resources over insecure HTTP, and browsers upgrade or block mixed-content requests by resource type. Scope: MDN documents current browser categories and behavior; individual browser versions may differ at the margins. Confidence: high · Verified: MDN: Mixed content

The trap que reassures personnes falsely is the anchor tag. A <a href="http://…"> lien to an HTTP page is pas mixed content — it navigates to a nouveau document; it doesn’t charger an insecure resource into the current secure un. That’s vrai of quelconque top-level navigation to an HTTP page, pas simplement anchor clicks.

It’s encore worth sending outbound liens to HTTPS destinations. Sous the modern browser-default Referrer-Policy (strict-origin-when-cross-origin), a click from an HTTPS page to an HTTP destination fait drop the Referer header, qui peut mangle referral analytics — but que behavior is policy- and browser-dependent, pas a universal rule: une page (or an upstream proxy/CDN) que sets a looser Referrer-Policy peut encore send a referrer on que downgrade. Vérifier the réel Referrer-Policy in effect avant asserting how beaucoup referral données a donné site loses — but in quelconque cas, that’s a separate problem from mixed content, pas mixed content itself.

Active vs. passive: the distinction que sets votre priorities

Modern navigateur and W3C documentation classifies mixed content primarily as upgradable versus blockable content — resource types le navigateur va silently retry over HTTPS versus ones it refuses outright — plutôt que the older active/passive split. Active/passive is encore utile shorthand pour pourquoi navigateurs draw que line (how beaucoup of lune page the resource pourrait compromise), and it’s how Google’s propre explainer frames it, so it’s kept ci-dessous as the principal triage framing — simplement don’t treat it as the current official taxonomy quand vous devez raison à propos de a spécifique resource type; voir the exceptions après the two listes.

Navigateurs classify mixed content by how beaucoup of lune page the insecure resource pourrait compromise. Google: “Active mixed content poses a supérieur threat que passive mixed content.” Que unique sentence devrait drive votre triage order.

Active mixed content interacts with — and peut prendre over — the whole page. Google describes it as “scripts, stylesheets, iframes, and quelconque autre code le navigateur peut download and execute.” En pratique the active liste is:

  • <script src="http://…"> — the worst cas; an intercepted script peut rewrite the entier DOM, exfiltrate formulaire données, or inject content.
  • <link rel="stylesheet" href="http://…"> — CSS peut hide, reposition, or overlay anything, so it’s treated as active.
  • <iframe src="http://…"> — an embedded insecure document à l’intérieur votre secure un.
  • XMLHttpRequest / fetch() to http:// — insecure données lune page alors acts on.
  • Web fonts, <object>/<embed> resources, and the <link> variants que pull in executable or layout-controlling content.

Parce que a tampered active resource peut rewrite lune page, “La plupart navigateurs déjà block ce type of content by par défaut to protéger utilisateurs.” That’s pourquoi active mixed content is ce que visibly breaks choses après a migration — a blocked stylesheet strips votre CSS, a blocked script kills interactivity, a blocked iframe leaves a hole. Fix active premier. It’s a functional bug, pas simplement a security nag.

Passive (afficher) mixed content — Google: “including images, video, and audio”“doesn’t interact with the rest of the page.” An intercepted image peut be swapped but can’t seize the document. So historically navigateurs chargé it and simplement downgraded the indicator: “Jusqu’à recently, passive mixed content was chargé in tout navigateurs, parce que blocking it voudrait have broken nombreux websites. Ce is now beginning to modifier.” The direction of travel à travers navigateurs is toward auto-upgrading passive resources to HTTPS où possible and blocking ce que can’t be upgraded, so “passive = harmless” is ne … plus a safe assumption to construire on.

Exceptions the active/passive split doesn’t capture

The upgradable/blockable line has several exceptions que don’t follow the general “images upgrade, scripts block” pattern ci-dessus — ces are the cas que en réalité trip personnes up En pratique:

  • CORS-enabled image requêtes are force-failed, pas upgraded. An ordinary <img src="http://…"> is upgradable, but an image requête made with crossorigin définir is treated differently by the mixed-content algorithm and fails au lieu de silently upgrading.
  • srcset and <picture> candidates are blockable, pas upgradable. The même image, requested via a responsive-image mechanism au lieu de a plain src, falls into the blockable category — don’t assume every image référence behaves the même façon.
  • IP-address hosts are blocked, pas upgraded, même pour an otherwise-upgradable resource type. A référence comme http://203.0.113.5/logo.png doesn’t obtenir the automatic-upgrade treatment a domain-hosted equivalent voudrait.
  • Nested contexts and workers are in scope. Mixed-content checks appliquer à l’intérieur iframes and à l’intérieur service/shared workers aussi, pas simplement the top document — a worker fetching an insecure script is encore mixed content.
  • Local and loopback origins have leur propre nuance. localhost, loopback addresses, and file:// contexts are “potentially trustworthy origins” sous the spec même sans TLS, so a simple HTTP-vs-HTTPS heuristic doesn’t map cleanly onto local development environments.
  • Insecure downloads are a connexe but separate boundary. A download initiated from a secure page over http:// is a réel risk, but it’s governed by its propre download-security handling, pas the sub-resource mixed-content rules in ce section.
  • Top-level HTTP navigation encore isn’t mixed content, notamment the anchor-link cas ci-dessus — that’s a property of navigation, pas of a chargé sub-resource, cependant nombreux of ces autre exceptions appliquer.

Detecting mixed content — the whole stack

Là is aucun unique button, and chaque couche ci-dessous réponses a différent question — a clean result at un couche doesn’t clair the others. Diagnose récupéré source (ce que the raw HTML en réalité références), rendered/runtime state (ce que the navigateur requêtes une fois it’s parsed lune page and run its scripts), and réel utilisateur sessions (ce que se produit pour a visitor behind a consent banner, a geo-redirect, a login wall, or a third-party tag que seulement fires sous spécifique conditions) separately. Couche ces from “one page” to “whole site”:

  1. The Chrome DevTools console (rendered/runtime state). Charger the HTTPS page and ouvrir the console. Blocked active mixed content logs a message along the lines of “Mixed Content: Lune page … was chargé over HTTPS, but requested an insecure … Ce requête has been blocked; le contenu doit be served over HTTPS.” Passive que obtient chargé logs a warning plutôt que a block. The Security panel (or the Problèmes tab) groupes it up par page. Fast pour spot-checks and pour confirming a spécifique fix — but treat the exact message wording, panel layout, and même qui resource types obtenir blocked as navigateur- and version-specific; ce was confirmed contre Chrome as of 2026-07 and vous devez vérifier current wording on the réel navigateur/version you’re diagnosing plutôt que quoting it as a fixed UI string, and expect Firefox, Safari, and Edge to differ.

  2. A site robot d’exploration (récupéré source, at scale). DevTools is per-page; a explorer is site-wide. Ahrefs Site Audit and Screaming Frog les deux flag pages que référence http:// sub-resources on an HTTPS site — the seulement realistic façon to trouver mixed content à travers thousands of URLs. Ce is the principal outil pour an audit, but it’s encore reading source: a explorer passing clean doesn’t prove the rendered page or a réel session is clean aussi — record qui navigateur/outil/version produced a donné result plutôt que reporting un unqualified réussir/échouer.

  3. CSP violation reporting (réel utilisateur sessions). Vous pouvez faire the navigateurs of réel visitors report mixed content back to vous, qui catches resources que seulement charger on certain pages, pour certain utilisateurs, sous certain consent states, or from third-party tags vous don’t contrôler — the couche neither a explorer nor a unique DevTools vérifier peut reach. web.dev: “Vous pouvez utiliser content security policy to collect reports of mixed content on votre site. To enable ce fonctionnalité, définir the Content-Security-Policy-Report-Only directive by ajout it as une réponse header pour votre site.” Report-Only mode reports violations sans enforcing the policy, so vous pouvez mesurer the problem in production avant vous turn on blocking. (The mechanism is the modern report-to / Reporting-Endpoints header, or the older report-uri. Remarque ce is a différent, general-purpose report-only policy que upgrade-insecure-requests itself — putting que spécifique directive in report-only mode doesn’t fonctionner, as covered ci-dessous.)

Evidence for this claim upgrade-insecure-requests in a Content-Security-Policy-Report-Only header is ignored. Scope: Content Security Policy upgrade-insecure-requests processing Confidence: high · Verified: Upgrade Insecure Requests

Utiliser tout three: DevTools to vérifier a rendered page, a robot d’exploration to inventory récupéré source, CSP reports to catch the real-session long tail que seulement montre up in the wild. Un explorer passing is evidence à propos de the source, pas a guarantee que every consent state, ad-tech variant, personalization branch, or worker is clean.

Fixing at the source

The réel fix starts avant vous touch a unique référence: vérifier the HTTPS equivalent en réalité exists, presents a valid certificate, and renvoie le contenu vous expect — don’t assume swapping the scheme is safe simplement parce que the domain resolves. Une fois that’s confirmed, every sub-resource référence devrait resolve over HTTPS. Options ci-dessous are in rough order of preference, but chaque un encore dépend on ownership and context, pas simplement the string vous type:

  • Absolute HTTPS URLs — modifier http://cdn.example.com/app.js to https://cdn.example.com/app.js. Explicit and unambiguous; the safest par défaut quand you’re pas certain à propos de the serving context ci-dessous.
  • Root-relative or relative paths — pour resources vous propre on the même site, /assets/app.js inherits lune page’s scheme automatically. Google’s HTTPS guidance: “Assurez-vous intrasite URLs and external URLs don’t depend on a spécifique protocol. Utiliser relative paths or leave out the protocol as in //example.com/something.js.” Treat ce as conditional, pas a universal recommendation: it seulement holds une fois you’ve confirmed vous en réalité propre the resource (a relative chemin to a third-party asset doesn’t faire sense), que lune page’s réel base URL resolves the façon vous expect (a <base> tag, a proxied chemin, or an embedded/AMP context peut modifier ce que “relative” signifie), and que nothing downstream reconstructs l’URL in a façon que reintroduces http:// — client-side code building une URL from window.location or a stored absolute valeur, Par exemple.
  • Protocol-relative URLs (//example.com/something.js) encore fonctionner, but they’re pas the preferred universal fix — gate les on the même ownership/base-URL checks ci-dessus, pas simplement habit. On an all-HTTPS web, an explicit https:// is usually clearer and avoids surprises si the fichier is ever opened from a non-HTTP context; reach pour protocol-relative seulement où vous have a spécifique raison pas to hard-code the scheme.

At scale vous almost jamais hand-edit templates un by un — but don’t run an unguarded database string-replacement contre production soit. http://yourdomainhttps://yourdomain semble comme a simple find-and-replace, and pour plain-text fields it souvent is safe, but CMS content peut be serialized or structured (PHP serialized arrays, JSON blobs, block-editor données) où a naive substring swap corrupts the record au lieu de fixing it. Utiliser application-aware tooling que understands the serialization format, back up the database premier, and dry-run the replacement so vous pouvez examiner the affected rows avant committing. Alors fix the handful of template/config fichiers que emit l’URLs; the robot d’exploration and CSP reports mop up the stragglers.

upgrade-insecure-requests: the safety net (and its limites)

The proactive backstop is a Content-Security-Policy directive. web.dev: “The upgrade-insecure-requests CSP directive instructs le navigateur to upgrade insecure URLs avant making network requêtes.” Définir the header:

Content-Security-Policy: upgrade-insecure-requests

Per MDN, it “instructs utilisateur agents to treat tout of a site’s insecure URLs (ceux served over HTTP) as though ils have been replaced with secure URLs (ceux served over HTTPS).” Concretely, MDN says it upgrades: “requêtes to charger resources (tel as images, scripts, or fonts),” “navigation requêtes (tel as lien targets) qui are same-origin with the document,” “navigation requêtes in nested browsing contexts, tel as iframes,” and “formulaire submissions.” Evidence for this claim The upgrade-insecure-requests CSP directive rewrites insecure URLs as secure URLs before requests are made. Scope: MDN documents the directive's rewriting behavior and limits; it does not guarantee that an HTTPS version of every resource exists. Confidence: high · Verified: MDN: CSP upgrade-insecure-requests

Two operational details matter au-delà que quote. Premier, the sub-resource upgrade isn’t limited to same-origin requêtes — it’s the navigation upgrade that’s same-origin-only per the quote ci-dessus; ordinary sub-resource requêtes obtenir rewritten à travers origins aussi, so a CDN-hosted script or a third-party font obtient upgraded, pas simplement same-site assets. Second, the rewrite se produit avant le navigateur’s mixed-content and CSP checks evaluate la requête, qui is pourquoi a resource que voudrait sinon be blocked outright as mixed content peut charger cleanly une fois it’s been upgraded — the upgrade pre-empts the block.

Three limites vous doit pas paper over:

  • It ne fait pas upgrade third-party top-level navigation. MDN: “Cependant, top-level navigation requêtes whose target is a différent origin ne va pas be upgraded.” Parce que of que, it is explicitly pas a replacement pour HSTS: “The upgrade-insecure-requests directive ne va pas garantir que utilisateurs visiting votre site via liens on third-party sites va be upgraded to HTTPS pour the top-level navigation and thus ne fait pas replace the Strict-Transport-Security (HSTS) header.” (Plus on que split ci-dessous.)
  • It’s a net, pas a fix, and it doesn’t fall back. Si the resource genuinely isn’t disponible over HTTPS, the upgraded requête simplement fails outright — it fait pas fall back to the original http:// version. Cleaning the source is encore the job; the directive covers ce que vous missed, pas what’s genuinely broken.
  • Report-only mode doesn’t perform the upgrade — it’s a no-op. Putting upgrade-insecure-requests à l’intérieur a Content-Security-Policy-Report-Only header is ignored by le navigateur: nothing obtient rewritten, and nothing obtient reported pour it soit. Si vous vouloir visibility into ce que the upgrade voudrait affecter avant vous enforce it, run a separate, general-purpose report-only policy que reports disallowed http:// destinations (the même default-src https: report-only approach utilisé pour detection ci-dessus) — vous pouvez’t obtenir que visibility by making upgrade-insecure-requests itself report-only.

block-all-mixed-content — mostly historical

There’s a companion directive, block-all-mixed-content, qui — per MDN — “prevents loading any assets over HTTP when the page uses HTTPS,” notamment “les deux blockable and upgradable mixed content,” and s’applique to iframes aussi. En pratique it’s been superseded. MDN marks it deprecated and “obsolete in the specification,” noting: “Content que isn’t blocked is now toujours upgraded to a secure connection, so ce directive n’est pas nécessaire.” Reach pour upgrade-insecure-requests; treat block-all-mixed-content as legacy vous pourrait inherit, pas something to deploy nouveau. Si vous déjà send upgrade-insecure-requests, block-all-mixed-content has nothing left to do pour upgraded requêtes — the upgrade rewrite se produit premier, so by the temps a block-all vérifier voudrait run, la requête has déjà been upgraded (or has déjà failed). It’s pas simplement legacy; it’s redundant wherever UIR is déjà deployed.

Evidence for this claim block-all-mixed-content is deprecated and obsolete for new deployment. Scope: legacy CSP directives Confidence: high · Verified: CSP: block-all-mixed-content

Pourquoi votre CMS garde reintroducing it

Mixed content isn’t a one-time cleanup — it recurs, parce que several systems quietly re-inject http:// URLs après vous think you’re fait:

  • Le contenu database. In WordPress, Drupal, and la plupart CMSes, editors paste images and embeds with absolute http:// URLs straight into post bodies. Ceux live in the database, pas in a template, so a code-level fix jamais touches les — hence the DB search-and-replace.
  • Themes and plugins. A theme or plugin que hard-codes an http:// asset URL (a font, a script, a background image) reintroduces mixed content on every page it renders, and a plugin mettre à jour peut bring it back après you’ve cleaned it.
  • Ad tech, analytics, and third-party tags. Tag managers, ad networks, chat widgets, and analytics snippets charger leur propre sub-resources — and si a vendor’s tag encore calls http://, it’s mixed content vous pouvez’t fix in votre propre codebase. Ce is exactly the long tail CSP reporting is pour; the durable fix is pressing the vendor to serve over HTTPS (or dropping the tag). Si a vendor has aucun working HTTPS endpoint, the durable choices are the même three: obtenir les to fix it, replace the dependency, or drop it — là isn’t a fourth option que garde the insecure version running safely.
  • Service workers and caches. A service worker peut cache une réponse (or the requête itself) que encore points at http://, and it’ll garder serving que stale référence on repeat visits même après vous fix the source. Reproduce a suspected fix in an incognito/uncached session avant concluding it didn’t fonctionner, and faire certain a deploy que changements reURL sources aussi bumps the service worker/cache version so stale entries obtenir evicted plutôt que replayed.
  • Hard-coded http:// in old content and email/print templates que obtenir reused.

The operational takeaway: bake detection into a recurring audit (robot d’exploration + CSP reports), pas a launch-day checklist vous run une fois.

How mixed content interacts with HSTS

Mixed content and HSTS solve adjacent but différent problems, and conflating les is a courant mistake:

  • upgrade-insecure-requests fixes sub-resources votre propre secure page requêtes — it upgrades the images/scripts/iframes lune page pulls in.
  • HSTS (Strict-Transport-Security) forces the top-level navigation to votre site onto HTTPS — même the very premier requête, avant quelconque redirection fires — and defends contre SSL-stripping. Google frames HSTS as a façon to “éviter the cost of the 301 redirection” and to “defeat attacks comme SSL Stripping.”

Ils don’t substitute pour chaque autre. As MDN spells out, upgrade-insecure-requests “ne va pas garantir que utilisateurs visiting votre site via liens on third-party sites va be upgraded to HTTPS pour the top-level navigation and thus ne fait pas replace the Strict-Transport-Security (HSTS) header.” A entièrement hardened setup uses les deux: upgrade-insecure-requests (or clean URL sources) so the secure page has aucun insecure cargo, and HSTS so nobody reaches le site over HTTP in the premier placer. And the usual HSTS caution encore s’applique — Google: “Don’t enable HSTS jusqu’à you’re certain votre site operation is robust suffisant to éviter ever deploying HTTPS with certificate validation errors,” and preloading is fermer to a one-way door.

Fait mixed content hurt SEO directement?

Lead with the direct effects, parce que they’re the ones vous en réalité contrôler: mixed content is premier a security and functional problem. Blocked active mixed content breaks rendering and interactivity outright — a manquant stylesheet or script is a réel regression regardless of ce que a moteur de recherche rend of it. That’s raison suffisant to fix it avant vous think à propos de rankings at tout.

The SEO consequences are réel but conditional, pas direct or guaranteed. Current official Google guidance ne fait pas establish fixing mixed content as a direct ranking boost — the HTTPS ranking signal itself is scheme-based (si l’URL starts with https://), pas a sub-resource cleanliness vérifier, so a stray insecure image doesn’t by itself cost vous “the HTTPS signal.” But downstream effects peut encore montrer up selon what’s en réalité broken: si Googlebot renders une page whose CSS or JS was blocked as mixed content, it may index a broken or incomplete version; a downgraded security indicator peut hurt utilisateur trust, engagement, and conversions même with aucun ranking modifier at tout; and Google’s general preference pour HTTPS canonicals is itself conditional — invalid certificates, insecure dependencies, HTTPS-to-HTTP redirections, or conflicting canonical signals elsewhere on lune page peut tout modifier qui URL obtient choisi, independent of mixed content specifically. Treat rendering, indexation, canonicalization, and analytics effects as choses to vérifier on votre propre pages, pas universal outcomes to promise — and fix mixed content pour the security and functional raisons premier.

Ce sits à l’intérieur the broader HTTPS pour le SEO topic, qui covers the migration playbook, the ranking-signal weight, and HSTS in complet; si you’re aussi debugging the certificate itself (chain errors, expiry, DV/OV/EV), that’s a sibling deep dive.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.