60

Stack Overflow has HTTPS in some places! However, this breaks most existing image links. Could those be made protocol-relative, or react to the requesting protocol, or just always use HTTPS?

The same applies to .sponsor-tag-img.

  • I don't think always using HTTPS would be a good choice, even if it only applied to imgur links. This would increase the latency of the image download, which could have a significant impact on mobile clients, and often have no benefit. Protocol-relative on a web-page would be the way to go. – Aaron Brager Feb 15 '14 at 19:33
  • Also, if the same image URL information is used to generate payloads for the Stack Exchange iOS/Android apps, the image should almost always be HTTP since mixed protocols isn't an issue there. – Aaron Brager Feb 15 '14 at 19:34
  • 3
    @AaronBrager: Mixed protocols aren’t disallowed for fun. It’s a security (well, privacy) problem. Yes, even globally-accessible images without cookies. – Ry- Feb 15 '14 at 20:05
  • Right, but on web non-private images are commonly sent via HTTPS to avoid mixed protocol errors. My point was simply: if the images are not private, it's wasteful to use HTTPS to transmit them. – Aaron Brager Feb 15 '14 at 20:14
  • 1
    Nick does discuss this in his blog post on bringing SE to HTTPS: Inline Images: we can’t include insecure content on the page…so that means turning our images to SSL when i.stack.imgur.com is ready. For other domains images are embedded from we have to turn them into links, or solve via another approach. – hichris123 Feb 15 '14 at 22:38
  • 5
    @hichris123: Yes, i.stack.imgur.com has supported HTTPS for a while. – Ry- Feb 18 '14 at 20:39
  • 3
    Investigating a different SSL issue, I noticed that gravatars cause mixed content messages to the console as well. Since Gravatar does support HTTPS, fixing both issues at the same time should be feasible. – MvG Mar 24 '14 at 7:20
  • 3
    If rewriting image URLs in posts is too much work, could we at least get this fixed for user avatars uploaded to i.stack.imgur.com? Gravatar images already seem to be using protocol-relative URLs, so it seems like at least some similar code must already be in place. – Ilmari Karonen Jul 23 '14 at 19:47
  • 3
    @Oded almost two years later, is this still planned? – Shadow The Curly Braced Wizard Nov 30 '15 at 8:44
  • I have no idea what the status of this is, but you could always use Camo Proxy Server. – DavidB Oct 9 '16 at 16:15
  • @DavidB: They don’t even need to do that for the internal i.stack images. – Ry- Oct 10 '16 at 23:50
  • @Ryan: No they don't. To be completely honest I don't know much of anything about Camo. I have never used it. I just know what it is and what purpose it serves. – DavidB Oct 11 '16 at 0:00
  • @AaronBrager That's why protocol-relative URLs are such a good fit for this; for those browsing over HTTP for one reason or another, they fetch the images over HTTP, but for those who browse over HTTPS, the images (or whatever other resource is being requested) are fetched over HTTPS. Especially now that Stack Exchange (sans site-specific metas) is mostly usable over HTTPS only, that at least puts the user in control. – a CVn Nov 25 '16 at 19:05
4

Not exactly as requested, but all image embeds are https:// now, as part of deploying HTTPS across the network. This causes fetching over HTTP/2 and results in a faster experience.

2

The just released Stack Overflow Unofficial Patch v1.14 includes a client-side work-around for this issue.

Ideally, such a work-around would intercept any requests for image files over HTTP and rewrite them to use HTTPS. However, while this is possible for a browser extension like HTTPS Everywhere, I'm not aware of any cross-browser way to do it with a simple user script like SOUP.

Instead, the way this work-around works is by detecting images that:

  1. have failed to load,
  2. have a http: URL on a page loaded over https:, and
  3. are on a domain known to support HTTPS simply by changing the protocol in the URL.

Notably, condition #1 means that this work-around only applies if your browser is configured to block insecure images on secure pages. For Firefox, this setting is available on the about:config page as security.mixed_content.block_display_content. I'm not currently aware of any way to change this setting for other browsers.

This also means that you'll still get mixed-content errors in your browser error log; the work-around just reloads the images over HTTPS after they've failed to load over insecure HTTP.

Also, while SOUP does try to re-run the work-around code whenever new content is injected via AJAX or otherwise modified, it's possible that there may be some remaining cases where dynamically loaded images are not fixed properly. If you find any, please let me know.

The domains for which the work-around is enabled currently include:

  • imgur.com (including stack.imgur.com), used for user-uploaded images using the SE editor's upload tool, as well as for user avatars uploaded via SE;

  • gravatar.com, used for global user avatars (actually, gravatar images seem to be already loaded over HTTPS anyway, but I've included it just in case);

  • facebook.com, used for avatars for users logging in via Facebook;

  • wikimedia.org (including upload.wikimedia.org), a popular source of freely licensed images;

  • sstatic.net, used for some SE interface graphics, such as site icons (mostly loaded over HTTPS already, but IIRC I found some broken ones when I tested this); and

  • stackexchange.com and all other Stack Exchange sites (stackoverflow.com, superuser.com, serverfault.com, stackapps.com, askubuntu.com, mathoverflow.net), used e.g. for user flair images.

Some notable examples of domains to which the workaround is not applied include chart.apis.google.com (Google Charts, does not seem to support HTTPS) and imageshack.us (could be supported, but would require more complex URL mangling than just changing the protocol).


Just in case you're curious, here's the whole code, as included in SOUP v1.20.0:

if ( 'https:' != location.protocol ) return;
var urlRegex = /^http:\/\/(([a-z0-9\-]+\.)*((imgur|gravatar|facebook)\.com|wikimedia\.org|sstatic\.net|(stack(exchange|overflow|apps)|superuser|serverfault|askubuntu)\.com|mathoverflow\.net))\//i;
var fixImages = function (target) {
    $(target).find('img[src^="http://"]').each( function () {
        if ( ! urlRegex.test( this.src ) ) return;
        if ( ! this.complete || this.naturalWidth > 0 ) return;
        var newUrl = this.src.replace( urlRegex, 'https://$1/' );
        SOUP.log( 'soup mse221304 fixing img ' + this.src + ' -> ' + newUrl );
        this.src = newUrl;
    } );
};
SOUP.addContentFilter( fixImages, 'HTTPS image fix' );
$(document).on( 'mouseenter', '#user-menu', function () {
    SOUP.try( 'HTTPS image fix', fixImages, [this] );
} );
  • Why don’t you just make it replace all http: images, errored or not? (I do have everything configured to block passive mixed content, so it shouldn’t make any difference, but might prevent warnings.) – Ry- May 11 '14 at 0:34
  • 4
    @minitech: Because there's not much point -- the browser has already started to load the image before the script has a chance to kick in, so the insecure request has already been made (and may well have already completed). At that point, if the request wasn't blocked, reloading the image over HTTPS would be just closing the stable door after the horse has bolted. It would also waste bandwidth for users with insecure image loading enabled, since every image would be requested twice, first over HTTP and then over HTTPS. – Ilmari Karonen May 11 '14 at 0:40
  • 1
    chart.apis.google.com works now. – Maarten Bodewes Dec 24 '16 at 16:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .