With little fanfare, an important security change has arrived on the web. Now, all major browsers (except Safari) block non-secure downloads from a secure page.
|Edge 94+||Block with right-click “Keep” button|
|Chrome 94||Block Silently|
|Firefox 93||Block with “Allow download” button|
|Brave 1.30.89||Block Silently|
|Opera 79.0.4143.72||Block Silently|
You can test your browser’s behavior with this test page. In Edge 94, the block looks like this:
By right-clicking on the “can’t be downloaded securely” item, you can choose to continue the download anyway.
Firefox offers a very similar user-experience, although somewhat confusingly, they prompt for permission to save the file before blocking it:
The Chromium team started rolling out this protection last year. Over time, the Chrome block turned into a silent block (arguably confusing for users) where the only indication of an attempted/blocked download is a notice in the Developer Tools console:
Within Chrome or Edge, a user may use the Permissions UI to enable a secure site to download non-secure resources without blocking.
IT Administrator Override
The InsecureContentAllowedForUrls policy allows an IT administrator to exempt sites from mixed content blocking. List the origins that are allowed to request non-secure content/downloads (list the source page’s origin, not the target resource’s origin):
Discovering non-secure links
My MoarTLS browser extension makes it simple for you to see whether any of the links (including download links) on your page are non-secure:
… however, note that this tool only flags links that are directly non-secure– if the link goes to HTTPS but then subsequently redirects to (or through) HTTP, the tool won’t notice, but the browser blocker will.
The fact that the browser blocks the download if any URL used in a download’s source redirect chain is non-secure can lead to confusing UI whenever only a single URL is shown to the user. For instance, this download was blocked because the source page referred to HTTP but the request was subsequently redirected to the HTTPS URL shown:
Fixing HTTP Links
The first step in avoiding mixed content download blocking is to ensure that all of your resources are available over HTTPS; if a download isn’t available over HTTPS, updating the source page’s download link’s url to point to
https isn’t going to work.
The second step to avoiding blocking is to change all of the download links from HTTP to HTTPS.
Unfortunately, this might be much easier said than done– you might have hundreds of pages with hundreds of links.
What to do?
One approach is to use automation to rewrite links, either as a one-time job, or as a dynamic rewrite. When I was first building my test page above, I couldn’t figure out why it wasn’t working. It took a good 15 minutes to realize that I’d configured Cloudflare to automatically rewrite HTTP links to HTTPS. (In the Cloudflare Control panel, select SSL/TLS > Edge Certificates and enable Automatic HTTPS Rewrites.)
Content-Security-Policy offers an Upgrade-Insecure-Requests (UIR) directive that upgrades all of a page’s embedded resource URLs from HTTP to HTTPS. This is a great approach for fixing mixed content bugs without doing a lot of work on every page. Unfortunately, file downloads are typically treated as “Navigation requests”, which means that a UIR rule on
https://example.com will upgrade
http://example.com/dl/somefile but UIR will not upgrade
https://othersite.example.com/dl/somefile because it is not same-origin to the original page. Bummer.
You might hope that just putting your download site on the Strict-Transport-Security (HSTS) pre-load list might fix things because doing so ensures that your site is always contacted over HTTPS. Unfortunately, for historical reasons, HSTS is evaluated after mixed content blocking and so this approach does not work. But the Chromium team is considering whether blocking should be bypassed if non-secure requests in the download flow were upgraded to HTTPS via HSTS or the browser’s “Always use HTTPS” setting such that every URL that actually hit the network was secure.
Today, if you try to close the browser without explicitly aborting the blocked download, Edge complains at you. I’ve filed feedback that we should just cancel.
HTTPS for all the things!