1

I'm working on web app that communicates with a locally installed desktop application to get certificate information from the user machine and perform digital signatures.

Currently it's possible to auto generate keys and perform digital signatures with these auto generated keys in javascript using window.crypto. However there is no way to through javascript or html to access the user keys issued by a vendor CA installed on OS or Firefox keystore to perform digital signatures, this is why we relay on installed native application.

This native application is a porting of an old java applet because - hopefully - soon this technology will be not supported for all major browsers (currently it's not already supported in Chrome since September 2015, and also is not supported in Edge), besides the java plugin itself it'll be deprecated in Java 9. Currently we've a Java Web Start working but it's a requeriment to have an alternative way to perform the signatures, since JNLP is not very user frendly way to do so: it requires to download each time a JNLP on a user machine with the signature configuration, there is no communication from browser to JNLP and it's necessary to perform AJAX polling to the backend to check if the signature is finished...

The native application is basically a local http server which exposes the business methods through a REST API, this way it's easy to use from our web app with simply making some AJAX calls an dealing with the result.

It works flawlessly when the web app is deployed in HTTP, the problem is that our web app is secured under HTTPS, but our native application is an HTTP server, so evidently for security reasons by default the major browsers block our AJAX calls from the web app to our native application due to mixed content.

Any CA vendors will issue a server certificate for a localhost domain, and furthermore since the native application is installed on client, the private key will be available on every client machine, so for sure a certificate issued by a official CA it's not a possibility. Also note that our native application must work on a heterogeneous environments: different OS, different browser, different networks so a proxy solution for the SSL is also not an option.

A possible solution which come to my mind is to generate a self-signing certificate and configure our native application to work as an HTTPS server. However I see a flaw in this solution: the native application automatically or the client manually must install this certificate in the client SO trust store or in the firefox trust store, this is a security concern because you're adding a self-signed certificate in a trust store.

My question are:

  • Installing a self-signed server certificate for localhost directly in the trust store it's a security concern, but how is it really dangerous/exploitable? If you issue the cert for CN=127.0.0.1 if there is no proxy on the network or hosts edited it's not possible to a third party server serves content for you there, isn't? Is this solution as bad as it sounds?

  • There is an alternative way to communicate between web app in HTTPS with a native application in a easy manner, user-friendly way and supported for all major browsers?

4
  • it sounds like you are trying to bypass the browsers security. If you have a desktop app installed on the client machine anyway, why not put your webpage in that app instead
    – Ewan
    Nov 25, 2016 at 9:52
  • @Ewan thanks for you comment :), the thing is that the native application is only a single operation part of the all web application flow, so putting the webpage in the app is not a possible scenario.
    – albciff
    Nov 25, 2016 at 9:55
  • well it would be technically possible. which your current solution, by design of web browser security, is not. Perhaps if you gave ore detail on what the local client thing is trying to achieve we could suggest an alternative method
    – Ewan
    Nov 25, 2016 at 10:00
  • @Erwan basically the native application does what I describe in the question: desktop application to get certificate information from the user machine and perform digital signatures., At first I though that this it's enough because I'm sure that there is no browser way (js, html...) to access client certificate other than authenticating SSL connection, so to perform digital signatures over documents with the user keys on the keystore OS it's not currently possible. Anyway I'll try to update my question to show more details :).
    – albciff
    Nov 25, 2016 at 10:08

1 Answer 1

6

THE ORIGINAL SOLUTION IS NOT VALID ANYMORE!

Updated Solution

Everyone doing this (github, spotify, blizzard, dropbox, etc) have all seen their certificate revoked last year because the private key was stored locally and considered compromised.

There are 2 workarounds:

  1. create, locally, an ssl certificate binded to localhost/127.0.0.1 and install it in the OS trusted keystore.
  2. In the Secure Contexts Spec, localhost/127.0.0.1 is now considered a potentially trustworthy origin. This means that an HTTPS page calling 127.0.0.1 over http is NOT blocked by Mixed Content. Tested in Edge, Chrome and Firefox. Unfortunatly, Microsoft team has not backported this fix to IE.

If origin’s host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".

Original Solution

You get a standard certificate from a CA for a domain like local.myapp.com and you associate this host with 127.0.0.1 in your dns.

This will enable https calls from your web page to your installed app.

Please note that there may be security issues with this. In fact Chromium intend to block these calls to localhost (or add an option to opt-in --> https://bugs.chromium.org/p/chromium/issues/detail?id=378566). But multiple sites are doing this:

  • Spotify (web player - desktop app) : *.spotilocal.com
  • Github (open file in Github for Mac) : ghconduit.com
  • Dropbox : www.dropboxlocalhost.com

Explanation of how Spotify does it: http://cgbystrom.com/articles/deconstructing-spotifys-builtin-http-server/

With the requirement to use HTTPS, a valid SSL certificate is needed to avoid browsers complaining. Spotify has worked around this problem by registering a domain (*.spotilocal.com) that merely points to 127.0.0.1. But rather than connecting to the top domain, they use a wildcard domain and connect to a random subdomain each time (for example abcrjdknsa.spotilocal.com). The reason for this is to avoid the browser’s max connection limit per domain, enabling more tabs in the browser to concurrently use their API at the cost of an extra DNS lookup.

4
  • wow! I read the spotify article a bit... I'll take a more deep look on it later... but ping to any domain in *.spotilocal.com resolving to 127.0.0.1 looks promising. Thanks :) +1!
    – albciff
    Nov 25, 2016 at 17:27
  • I review this and make some tries, and it works correctly, and for the user perspective the functionality is clean and doesn't require an action for their part, the problem is that I must embed a valid private key for server certificate in the native application, this action implies that my key could be stolen so I've to think about the risk of this. Anywise thanks for the answer :).
    – albciff
    Nov 28, 2016 at 7:28
  • @albciff see updated answer. If someone tells your CA that you embed the private key locally it will get revoked (i think they have 24 hours to do so). Pretty hard denial of service... Feb 8, 2019 at 16:50
  • Thanks for the update, at first time I read the answer and I understand the model which I implement :). however I already saw that put a private (issued by a trusted ca) in a application is not a.good idea. I implement a diferent approach, for each installation we generate a fake ca, and issue a server certificate for this ca to protect nativa.aoclocal.cat (which domain resolves to 127.0.0.1) then the installation proces automatically install this ca in windows truststore. It's maybe not the best solution but this way each installation has a different ca and stole one only compromise this pc.
    – albciff
    Feb 9, 2019 at 20:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.