Moving to HTTPS when using external images

This blog run LetsEncrypt certificates for few months now without any issue. That's why I decided to move another web project to full HTTPS.

Moving to HTTPS is easy

Thank you LetsEncrypt.

I won't explain here how to get/install/renew certificates since a lot of web pages cover this topic already.

All these docs make the move from HTTP to HTTPS pretty easy.

But more complicated when using external media

I have a web project where the main content of each page is a picture coming from anywhere over the Internet. These media are chosen by the end-user himself, based on suggestions from a search API like Bing or Google.

The problems I faced where the following:

- the APIs do not provide a way to only ask media secured by HTTPS - I could filter urls on my side but the number of results using HTTPS is pretty low (<10% on the tests I made) - these external media may fallback to HTTP when they want - of course I can't do anything on these external websites

What will be the problem of loading HTTP images in a HTTPS website?

This is called mixed content and is generally visible in you browser console under this message:

Mixed Content: The page at 'https://www.my-site.com/' was loaded over HTTPS, but requested an insecure script 'http://www.my-site.com/something-called-using-http'. This request has been blocked; the content must be served over HTTPS.

This is visible in the browser with the following symptoms:

  • the media is not loaded, pretty annoying when this is the main content of your page
  • you loose the "Secured" green locker in the address bar

What's the solution?

The best solution I found is to rely on an Open Source project named camo. It's a proxy written in CoffeeScript & Ruby which will allow to use your secured domain to get content from anywhere on the Internet.

Camo is all about making insecure assets look secure. This is an SSL image proxy to prevent mixed content warnings on secure pages served from GitHub.

This project has been used by Github itself to secure external content.

A Ruby and a PHP clients are available. These library sign and encrypt URLs passed to camo to secure proxy usage.

Camo is pretty easy to install and run. The only issue is that you will get the trafic for these images and you bandwidth may suffer (but using Amazon Cloudfront on top of that may fill your needs)

If you find this article useful, or have another approach to cover mixed content when using external media, leave a comment.