Mixed Content (HTTP on HTTPS)
debt(d5/e5/b3/t7)
Closest to 'specialist tool catches it' (d5). The term's detection_hints.tools list includes chrome-devtools, why-no-padlock, mixed-content-checker, and lighthouse — all are specialist tools requiring intentional use. Mixed content does surface in the browser console, but only after HTTPS migration and only when the affected page is actually loaded; it is not caught by a default linter or compiler. Slightly above d3 because it requires deliberate testing with these tools and is not surfaced during development in non-HTTPS environments.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes a multi-step process: changing HTML template URLs, running a database find-and-replace on CMS content, auditing CSS files, and checking third-party embeds. This spans templates, stylesheets, database content, and potentially external providers — clearly more than a single-line patch (e1) or simple pattern replacement (e3), but not a full architectural rework (e7+).
Closest to 'localised tax' (b3). Mixed content applies to the web context only and is primarily a concern during and after HTTPS migration. Once fixed (URLs updated, CSP header set), it imposes minimal ongoing burden. It does not shape every future change or create a persistent productivity tax across the whole codebase, but CMS-stored URLs and third-party embeds mean it is not entirely a one-off fix.
Closest to 'serious trap' (t7). The misconception field explicitly states that developers believe mixed content only affects login or payment pages — when in reality any HTTP resource on an HTTPS page is an injection vector and active mixed content silently breaks functionality entirely. The why_it_matters note confirms that breakage is discovered only after users report it post-migration. This contradicts developer intuition that HTTPS secures the page regardless of individual resource URLs, warranting t7.
Also Known As
TL;DR
Explanation
Mixed content occurs when a page served over HTTPS loads sub-resources over HTTP. There are two types with different browser treatment: active mixed content (scripts, stylesheets, iframes, XMLHttpRequest) is blocked by all modern browsers since 2020 — the resource simply doesn't load; passive mixed content (images, audio, video) triggers a security warning and Chrome attempts to auto-upgrade to HTTPS. Mixed content undermines HTTPS because an attacker on the network can intercept and modify the HTTP resource, injecting malicious content into an otherwise secure page. The most insidious source is CMS databases — content editors add images with http:// URLs before HTTPS migration, and those URLs persist in the database long after the site moves to HTTPS. A find-and-replace in the database is required, not just template changes. Chrome DevTools Security tab shows exactly which URLs caused mixed content.
Common Misconception
Why It Matters
Common Mistakes
- Fixing HTML templates but not database content — CMS-stored image URLs with http:// persist after HTTPS migration and cause mixed content on every page load.
- Hard-coded http:// URLs in CSS (background-image, @font-face src) — easy to miss during migration.
- Third-party embed code using http:// for their own scripts — must contact provider or find HTTPS version.
- Not testing after HTTPS migration — mixed content only appears after the switch; dev environments often don't enforce it.
Avoid When
- Do not rely on CSP upgrade-insecure-requests as a permanent fix — it does not upgrade active mixed content in all cases and is not a substitute for fixing URLs at source.
When To Use
- Fix mixed content immediately on any HTTPS site — active mixed content is blocked and breaks functionality.
- Use CSP header 'upgrade-insecure-requests' as a safety net during HTTPS migration to auto-upgrade passive mixed content.
Code Examples
<!-- HTTP image on HTTPS page — passive mixed content warning -->
<img src="http://example.com/product.jpg" alt="Product">
<!-- HTTP script on HTTPS page — BLOCKED by browser -->
<script src="http://cdn.example.com/analytics.js"></script>
<!-- Use HTTPS for all resource URLs -->
<img src="https://example.com/product.jpg" alt="Product">
<script src="https://cdn.example.com/analytics.js"></script>
<!-- Protocol-relative URLs as a fallback -->
<img src="//example.com/product.jpg" alt="Product">
<!-- Fix CMS database content -->
<!-- UPDATE posts SET content = REPLACE(content, 'http://', 'https://') WHERE content LIKE '%http://%' -->