HTTPS Mixed Content: Still the Easiest Way to Break SSL
Last updated on: December 18, 2022
Mixed content issues arise when web sites deliver their pages over HTTPS, but allow some of the resources to be delivered in plaintext. The active network attacker can’t do anything about the encrypted traffic, but messing with the plaintext can result with attacks ranging from phishing in the best case to full browser compromise in the worst. A single exposed script is sufficient: the attacker can hijack the connection and inject arbitrary attack payloads into it.
We tend to talk a lot about other aspects of SSL/TLS, but mixed content is arguably the easiest way to completely mess up your web site encryption.
In the very early days of the Web, all mixed content was allowed; web browsers expected site operators to think through the consequences of mixing content. That, of course, did not result with great security. Site operators did whatever they needed to get their work done and decrease costs. Only in recent years did browser vendors start to pay attention and start to restrict mixed content.
Mixed content in modern browsers
Today, almost all major browsers tend to break mixed content into two categories: passive for images, videos, and sound; and activefor more dangerous resources, such as scripts. They tend to allow passive mixed content by default, but reject active content. This is clearly a compromise between breaking the Web and reasonable security.
Internet Explorer has been the leader in secure mixed content handling. As early as Internet Explorer 5 (according to this post), they had detection and prevention of insecure content by default. Chrome started blocking by default in 2011, and Firefox in 2013. The default Android browser and Safari, however, still allow all mixed content without any restrictions (and with almost non-existent warnings).
Here are the results of my recent testing of what insecure content is allowed by default:
Browser | Images | CSS | Scripts | XHR | WebSockets | Frames |
---|---|---|---|---|---|---|
Android browser 4.4.x | Yes | Yes | Yes | Yes | Yes | Yes |
Chrome 33 | Yes | No | No | Yes | Yes | No |
Firefox 28 | Yes | No | No | No | No | No |
Internet Explorer 11 | Yes | No | No | No | No | No |
Safari 7 | Yes | Yes | Yes | Yes | Yes | Yes |
They are mostly as expecting, but there’s a surprise with Chrome, which blocks active page content, but still allows plaintext XMLHttpRequest and WebSocket connections.
It’s worth mentioning that the table does not tell us everything. For example, browsers tend not to control what their plugins do. Further, certain components (e.g., Flash or Java) are full environments in their own right, and there’s little browsers can do to enforce security.
Testing for mixed content handling in SSL Labs
To make it easier to evaluate browser handling of this problem, I recently extended the SSL Labs Client Test to probe mixed content handling. When you visit the page, your user browser is tested, and you will get results similar to these:
Mixed content prevalence
Anecdotally, mixed content is very common. At Qualys, we investigated this problem in 2011, along with several other application-level issues that result with full breakage of encryption in web applications. We analysed the homepages of about 250,000 secure web sites from the Alexa top 1 million list, and determined that 22.41% of them used insecure content. If images are excluded, the number falls to 18.71%.
A more detailed study of 18,526 sites extracted from Alexa top 100,000 took place in 2013: A Dangerous Mix: Large-scale analysis of mixed-content websites (Chen et al.). For each site, up to 200 secure pages were analysed, arriving at a total of 481,656 pages. Their results indicate that up to 43% of web sites have mixed content issues.
Mitigation
The best defence against mixed content issues is simply not having this type of problem in your code. But that’s easily said than done; there are many ways in which mixed content can creep up. When that fails, there are two technologies that can come useful:
- HTTP Strict Transport Security (HSTS) is a mechanism that enforces secure resource retrieval, even in the face of user mistakes (attempting to access your web site on port 80) and implementation errors (your developers place an insecure link into a secure page). HSTS is one of the best thing that happened to TLS recently, but it works only on the hostnames you control.
- Content Security Policy (CSP) can be used to block insecure resource retrieval from third-party web sites. It also has many other useful features for to address other application security issues, for example XSS.
Hi Ivan,
after a very long search I thankfully found your article. With the Google Tag Manager I am already tracking JS-console errors. And on behalf of your Socket-Mixing-Article I wonder if it’s possible to track other non JS-issues such as blocked content due to mixed sockets as well. Hopefully you might have an idea.
EDIT: Want to note that the website has already loaded and the blocked connection occurs in an iFrame in Chrome.
Kind regards
Mike
Hello Ivan,
Thanks for the SSL Labs test link, it’s fantastic. Most of my clients are on WordPress, which can be a monster to fix all the mixed content since its not only absolute URLs in the database, but also hard coded in their template files.
Usually I use a quick fix plugin first, e.g. https://wordpress.org/plugins/force-https-littlebizzy/
Next, I will scan database, then one by one fix the hard code issues. Haven’t found a good online tool for that, but Chrome Console is okay.
Hey.do you have a poc for an exploit leveraging mixed content issues?