The default way the internet works is that the client (like a browser) makes a request for a resource located at a server, following which the server serves/rejects the request. Our requests are made under different URI schemes e.g. HTTP, HTTPS, FTP etc. For the time being, we will focus on the HTTP and HTTPS URI schemes. HTTP is the de facto scheme which is unsecured and hence far from used in standard production systems. HTTPS is HTTP running over SSL/TLS which renders content obfuscated thereby protecting it from eavesdroppers.
Browsers previously used to raise warnings which could be viewed in the console.
Fig.1 : Firebug console for Mixed Content Block
Of now, browsers block most of the active mixed content requests.
A word of note:
Firefox has a better (or different) “Mixed Content Block” implementation than Chrome. This difference exists due to the disparity in the definition of active mixed content by both the browsers. Firefox considers mixed iframes, XHRs and fonts as active category. Chrome’s implementation for mixed content blocking was less secure as it didn’t block mixed iframes and definitely not mixed XHRs. It’s since Chrome 30 that mixed iframes started being blocked. However, mixed XHRs were still left out. Firefox on the other hand, still blocks most of the active mixed content objects.
Mixed Content in WebSockets
WebSocket protocol (ws:// or wss://) is a new application layer protocol which lets build fast, full-duplex communication channels easily. Note that a ws:// or wss:// (ws secured) connection initiates via an HTTP/HTTPS session itself with a protocol upgrade. For more details, refer this link. So, going by the definition of Mixed Content, ideally an unsecured WebSocket connection ws:// should be dropped if initiated over from an HTTPS session and that all servers should be configured to communicate over WebSocket secured wss:// scheme.
Mixed Content Types
Mixed Content requests have been categorized into two broad categories, depending on the degree of vulnerability/entropy introduced into the application if the request were to be rendered.
- Passive/Display Mixed Content – Passive Mixed Content are those content which are isolated from the other sections of the application. Such content do not possess the power to alter other parts of the document. For e.g., images, audio, video content belong to such cohort. So, if there exists an MITM over such content, then say an audio content could be crippled or damaged, however this could not allow the attacker to take control of other parts of the application which the audio content was not a part of. Although, ideally all mixed content should be blocked, however browsers do not block Passive Mixed Content as they do not pose any severe threat to the application. Many websites rely on passive mixed content to work and that blocking them would leave behind an array of broken and dangling websites.
Expression in IE
width:expression(alert(‘you are busted !’);
-moz-binding in Firefox
Prevent Mixed Content blocking
As of now we’re fair to the fact that Mixed Content blocking arises due to HTTP content being requested over an HTTPS session. So, to solve the problem we’ve a few do’s and dont’s.
- If the application is served over HTTPS, then developers should ensure that all content needed are requested over HTTPS only and not over any other scheme.
- If some of the content needed is NOT available over HTTPS, then the provider should be contacted to apprise of the situation and request the access over HTTPS as well.
- Assuming that all content we need could also be rendered over HTTPS, then we as developers should always code the URLs etc. scheme un-prefixed. So, for example if we need to use google fonts for our application, then we might just use:
<!– whatever content you need –>
<link href=‘//fonts.googleapis.com/css?family=Open+Sans’ rel=‘stylesheet’ type=‘text/css’>
Note that the URL to the google font doesn’t have any scheme like https:// or http:// . This provides the browser the leeway to decide the scheme for the request depending on the scheme on which the application is being rendered. So, if we access the unsecured HTTP version of the application, the font will be accessed over HTTP and if the application is being accessed over HTTPS, then the scheme changes to HTTPS.
Blocking mixed content is however a step taken by browser vendors. The rational behind is quite legitimate, however is at the expense of the freedom of the developers and the cost of broken websites. I as a developer might not care much about the mixed content brouhaha and would like my browser to allow. However, we cannot expect our eavesdroppers to be magnanimous and hence it should go into the best practices list of every web developer to avoid mixed content altogether.
A Word of Caution
Another pressing concern for addressing the mixed content blocking is that Chrome is set to remove all Mixed Content XHRs and WebSocket connections in the next build. This ensures that neither any XHRs over HTTP nor any ws:// connection could be initiated by an application/document rendered over HTTPS. Firefox has been blocking mixed content websocket connections for a while now, this step ensures that all content goes over TLS now.
For further read, refer to this article. So, it’s better that we check our current implementations and change them to prevent our apps from breaking.