Mixed content issues arise when web sites use HTTPS to deliver their pages, but allow some of the resources to be delivered in plaintext (HTTP).
What can happen?
Mixing HTTP with HTTPS is almost as bad as not having HTTPS at all. Depending on what kind of resources are loaded in plain text (HTTP), mixed content may lead to:
- Phishing (show a fake page to the user with the intent to steal information)
- Sniffing (listening to communication between the client and server)
- Ability to craft injections by tampering with JavaScript and other resources
- Severe cache poisoning issues
Example of mixed content
A web site is encrypted over HTTPS, but fails to address HTTPS to certain resources such as:
- An image
- A stylesheet
- JavaScript
- An AJAX callback
- (or something else)
A Man-In-The-Middle (MITM) attacker may intercept the communication between your browser and the server and change the content of any of these resources.
Say a site loads jQuery over HTTP. All the attacker has to do is to replace the body of jQuery with a script of choice, compromising the full confidentiality and integrity the SSL (HTTPS) was supposed to provide.
Note that a web browser will send cookies even when asking for just an image or a stylesheet. If that request is not encrypted, an attacker could carry out an MITM attack and steal the user’s cookie, which may lead to session hijacking (attacker logging in as the user).
Remediation
Make sure everything is loaded over HTTPS. If you have a website with support for both HTTP and HTTPS, make sure to load resources using just // instead of https:// or http://.
<script src="http://example.com/example.js" type="text/javascript"></script>
Could be changed to:
<script src="//example.com/example.js" type="text/javascript"></script>
This will make the web browser use the same protocol for loading these resources as the one used to visit the site. In other words:
- If a user is visiting that site using HTTPS, example.js will be loaded over HTTPS.
- If a user is visiting that site using HTTP, example.js will be loaded over HTTP.
HTTP Strict Transport Security (HSTS)
You can also use HTTP Strict Transport Security (HSTS), 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 (you or your developers place an insecure link into a secure page).
HSTS is one of the best things that happened to TLS (Transport Layer Security) recently, but it works only on host names you control, e. g. you force your domain to be completely behind SSL. Any attempt to load resources from a third party CDN (Content Delivery Network) may still pose a risk.
Content Security Policy (CSP)
To handle the third party issue, Content Security Policy (CSP) was invented. It can be used to block insecure resource retrieval from third-party websites. It also has many other useful features that address other application security issues, for example XSS (Cross Site Scripting).
Secure cookies
As mentioned before in this article all cookies will by default be sent in all requests. Because of that sensitive cookies risk to leak if an MITMattack happens while you also visit an unencrypted page.
This can be prevented by adding the flag Secure to cookies. That way they will only be sent over https, and can therefore not be captured in an MITM attack.
Read more about how you do this in different languages here. If you have any questions, get in touch with us by emailing [email protected].
Resources
- Mozilla - How to fix a website with blocked mixed content
- Mozilla - Mixed Content
- Wikipedia - Strict Transport Security
- OWASP - Secure Headers Project
- OWASP - Content Security Policy
- HTML5 Rocks - An Introduction to Content Security Policy