Mixed content: the HTTPS padlock that is lying to your users
A secure page is only as secure as its weakest resource
You serve your page over HTTPS. The browser shows the padlock. As far as your visitor knows, everything on that page is encrypted and safe. But a web page is not one file — it pulls in scripts, stylesheets, fonts, images and trackers, often from several places. If even one of those is loaded over plain http://, you have mixed content: a secure page with insecure pieces inside it.
The padlock is making a promise the page is not fully keeping.
Why it actually matters
The whole point of HTTPS is that nobody between the user and the server can read or change what is sent. An HTTP resource on an HTTPS page travels outside that protection. That opens two real problems:
- It can be read. An insecure request can reveal information about what the user is doing on your supposedly private page.
- It can be changed. This is the serious one. If an attacker on the network can alter an HTTP resource in transit, and that resource is a script, they can inject code that runs inside your secure page — defeating the security HTTPS was supposed to give.
Active vs. passive mixed content
Browsers split mixed content into two tiers:
- Active content — scripts, stylesheets, iframes, fonts. These can change the behavior of the page, so a tampered one is dangerous. Modern browsers usually block active mixed content outright, which means part of your page silently breaks rather than loading insecurely.
- Passive content — images, audio, video. These cannot execute code, so the risk is lower, but they still leak over the network and the browser will downgrade the padlock or warn.
Either way, the visible result is the same: a security warning, a degraded padlock, or a broken feature.
Where mixed content sneaks in
It is rarely deliberate. Common sources:
- A hardcoded
http://URL left over from before the site moved to HTTPS. - A third-party widget or embed that defaults to HTTP.
- An old image or asset reference copied from somewhere insecure.
- A CDN or API link that was never updated to
https://.
How to fix it
- Load everything over HTTPS. Update any
http://resource URL tohttps://. Nearly every reputable provider supports HTTPS today. - Use protocol-relative carefully — or not at all. Prefer explicit
https://over older//URLs so intent is clear. - Add
upgrade-insecure-requests. This Content-Security-Policy directive tells the browser to automatically request HTTP resources over HTTPS, catching stragglers. - Replace anything that only offers HTTP. A resource that cannot be served securely should be dropped; it is a liability on an HTTPS page.
Check for mixed content
Mixed content is easy to miss because the page often still looks fine — until a feature breaks or a user sees a warning. An automated scan loads your pages and reports insecure resources pulled into your HTTPS site. Scan your site and find the HTTP links hiding behind your padlock.