SSL and mixed content due to CSS background images - css

I have a web page containing am entry form. HTTPS is enabled via an Apache redirect for all requests matching that page. Unfortunately, because the CSS pulls in external images using 'background-image: url(/images/...)', the browser will generate a warning message that the page contains mixed content.
What's the best way to resolve this issue?

Update 2014.12.17:
Now that SSL is encouraged for everyone and doesn’t have performance
concerns, this technique is now an anti-pattern. If the asset you > need is available on SSL, then always use the https:// asset.
Allowing the snippet to request over HTTP opens the door for attacks
like the recent Github Man-on-the-side attack. It’s always safe to
request HTTPS assets even if your site is on HTTP, however the reverse
is not true.
More guidance and details in Eric Mills’ guide to CDNs & HTTPS.
Source: Paul Irish – The Protocol-relative URL
Here is a very popular solution:
There's this little trick you can get away with that'll save you some headaches:
In HTML
<img src="//domain.com/img/logo.png">
In CSS
div{background: url(//path/to/image.png);}

You should also enable HTTPS for your static resources, and then make sure that the <link> refers explicitly to the HTTPS url for the CSS resource (whose relative urls will then be interpreted relative to the HTTPS base of the CSS file).

You should use full URL for your image:
https://your.domain.com/img/image.png`
or
https://your.domain.com/route/to/img/image.png
This solved my problem some time ago.

Related

https, a subdomain and an iframe: Any alternative to purchasing an additional SSL certificate?

I have a website example.com and an SSL certificate for this domain only. No subdomains except www are included. The site is based on Typo3.
On example.com/map is an iframe (note the subdomain):
<iframe src=„https://map.example.com“ width="400" height="300">
This doesn’t work with all browsers. Some browsers show an error (SSL_ERROR_BAD_CERT_DOMAIN) because the subdomain is not covered by the certificate.
The subdomain contains rather complex content which I wouldn’t know how to built in Typo3, that’s why I used an iframe.
Question:
Is there any way to insert the contents of map.example.com into the page example.com/map without purchasing an additional SSL certificate for the subdomain?
Thanks
Pida
I see the following solutions:
Get a certificate for map.example.com
Buy one
Use an ACME client, for example Let's Encrypt
Link: Instead of using an iFrame just link to the site map.example.com
Set up a reverse proxy
Server side include: Write an extension for the website example.com/map which includes the content from map.example.com
Rebuild the solution as TYPO3 extension
It is difficult to say which one fits best for you.
A server side include may be easy in some cases, but in most cases it requires a lot of search an replace for the content which is going to be pasted. It also requires to include asset files (images, javascript, css) either in the TYPO3 template or dynamically by parsing the whole include content.
A reverse proxy is easy to set up in case you have the required software components already installed an the required knowledge. Otherwise it requires some reading and some hours to set up.

some CSS can not show when swith the website from http to https

I have a website written in Ruby using Ruby on Rail framwork, everything was fine when using HTTP protocol, but when switching to HTTPS protocol.
Some CSS material can not shown, but some of it can.
The font can not be shown, originally the font was designed, but now it is not.
Anyone know what happen?
Without any specific error I assume browser is probably blocking files loading from mixed content, i.e. using both HTTP and HTTPS. Use your browser developer tools network tab to confirm this.
You can use // instead of http:// so that resources load from the relative protocol that the page content is loading from; Can I change all my http:// links to just //?
Also read; How to fix a website with blocked mixed content

Absolute (full) URLs without "http:" in HTML href

I have been seeing this a lot lately and I am unable to find any information on it.
Is there a name for it?
Which browsers support this?
It's the same as an absolute URL except that the schema will be the one used for the base URL. Thus, if you say //mysite.com/images/img.png on an https page, the image will be loaded with https and on an "ordinary" http page it will be loaded using the http schema (and, respectively, different default ports.)
This approach lets avoid the security warnings from browsers in the case when you have insecure content loaded by secure pages (and the pages can be loaded using both http and https protocols).

How do I refer to http resources on a https page safely?

I have enabled HTTPS for my site. Some of the resources such as css and js files on my pages come from another domain which is on HTTP. Now the problem is when I visit the page, browsers display an alert message. IE says "Do you want to view only the page content that was delivered securely" and FF says "You have requested an encrypted page that contains some unencrypted information. Information that you see or enter on this page could easily be read by a third party."
I tried the technique mentioned by Paul Irish which is not working.
Any idea how I can resolve this issue?
I use asp.net 3.5 for my site.
The assumption he makes in the referenced article I think you missed is
… assuming the site you're pointing to has this asset available on
both HTTP and HTTPS.
Those resources need to be served over HTTPS as well, or you will always get that message. I don't believe there is a way around it, and there likely shouldn't be a way around it. You want everything running over HTTPS for a reason.
You need to serve those resources over HTTPS.
The Firefox Mixed Content Blocking Announcement does a good job explaining the security risks.
If you own/control the other website where the resource files are located, a good solution might be to move the resource files over to the website where both HTTP and HTTPS are supported, and change both websites to point to those files at their new location.

Can I change all my http:// links to just //?

Dave Ward says,
It’s not exactly light reading, but section 4.2 of RFC 3986 provides for fully qualified URLs that omit protocol (the HTTP or HTTPS) altogether. When a URL’s protocol is omitted, the browser uses the underlying document’s protocol instead.
Put simply, these “protocol-less” URLs allow a reference like this to work in every browser you’ll try it in:
//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
It looks strange at first, but this “protocol-less” URL is the best way to reference third party content that’s available via both HTTP and HTTPS.
This would certainly solve a bunch of mixed-content errors we're seeing on HTTP pages -- assuming that our assets are available via both HTTP and HTTPS.
Is this completely cross-browser compatible? Are there any other caveats?
I tested it thoroughly before publishing. Of all the browsers available to test against on Browsershots, I could only find one that did not handle the protocol relative URL correctly: an obscure *nix browser called Dillo.
There are two drawbacks I've received feedback about:
Protocol-less URLs may not work as expected when you "open" a local file in your browser, because the page's base protocol will be file:///. Especially when you're using the protocol-less URL for an external resource like a CDN-hosted asset. Using a local web server like Apache or IIS to test against http://localhost addresses works fine though.
Apparently there's at least one iPhone feed reader app that does not handle the protocol-less URLs correctly. I'm not aware of which one has the problem or how popular it is. For hosting a JavaScript file, that's not a big problem since RSS readers typically ignore JavaScript content anyway. However, it could be an issue if you're using these URLs for media like images inside content that needs to be syndicated via RSS (though, this single reader app on a single platform probably accounts for a very marginal number of readers).
The question of whether one could change all their links to be protocol-relative may be moot, considering the question of whether one should do so. According to Paul Irish:
2014.12.17: Now that SSL is encouraged for everyone and doesn’t have performance concerns, this technique is now an anti-pattern. If the
asset you need is available on SSL, then always use the https://
asset.
If you use protocol-less URLs to load stylesheets, IE 7 & 8 will download them twice:
http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/
So, this is to be avoided for CSS if you like good performance.
Yes, network-path references were already specified in RFC 1808 and should work with all browsers.
Is this completely cross-browser compatible? Are there any other caveats?
Just to throw this in the mix, if you are developing on a local server, it might not work. You need to specify a scheme, otherwise the browser may assume that src="//cdn.example.com/js_file.js" is src="file://cdn.example.com/js_file.js", which will break since you're not hosting this resource locally.
Microsoft Internet Explorer seem to be particularly sensitive to this, see this question: Not able to load jQuery in Internet Explorer on localhost (WAMP)
You would probably always try to find a solution that works on all your environments with the least amount of modifications needed.
The solution used by HTML5Boilerplate is to have a fallback when the resource is not loaded correctly, but that only works if you incorporate a check:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- If jQuery is not defined, something went wrong and we'll load the local file -->
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
I posted this answer here as well.
UPDATE: HTML5Boilerplate now uses <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> after deciding to deprecate protocol relative URLs, see here.
If you would like to make sure all requests are upgraded to secure protocol then there is simple option to use Content Security Policy header upgrade-insecure-requests
Content-Security-Policy: upgrade-insecure-requests;
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests
I have not had these issues when using ://example.com - but you do need to add the colon at the beginning. Yoast had a good write up about this a while back. But it's lost in his pile of blog posts.

Resources