5

Is there a way to detect in JavaScript if the site was loaded over HTTPS using an SSL certificate untrusted by the browser (but accepted by the user)? I.e. it is invalid/expired/self-signed SSL certificate.

window.isSecureContext does not indicate this, it is true in all cases I tried on my own and on badssl.com if the page is loaded over HTTPS.

My use case: I am trying to use ApplicationCache but it refuses to work: on Chrome it fires the error callback with exception message "Manifest fetch failed (9)", on Firefox it fails silently.

As this means the browser behaves differently I hope it is detectable and I would like to make sure ApplicationCache is skipped altogether when it cannot be used.


I'd not like to create a seperate SSL connection from a JavaScript (user might have certs of custom CAs installed, etc.), nor try-catch an exception with ApplicationCache.

Gábor Héja
  • 458
  • 7
  • 17

2 Answers2

3

A webpage can not load over an untrusted SSL certificate. It might load over a certificate which is not publicly trusted but where the user has explicitly added an exception - which means that the user trusts the certificate.

It seems that you want to know instead if your site was loaded with a different certificate then your server provides, i.e. if there is some active man in the middle between the client and your server, like a SSL intercepting company proxy or a local antivirus product. For this you need to know the certificate details and compare these with your expectations. Unfortunately this is not possible from pure Javascript.

For more on this see Within a web browser, is it possible for JavaScript to obtain information about the HTTPS Certificate being used for the current page?, Is there a way to get SSL certificate details using JavaScript?. For an alternative approach of detecting the MITM at the server side see Detect man-in-the-middle on server side for HTTPS or Detecting HTTPS Interception (with the caddy webserver).

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • The browser behaves differently when the user overrides its decision to trust the certificate or not - see the ApplicationCache example in the question. I would like to know if this is the case or the certificate is valid. – Gábor Héja Jan 16 '20 at 09:09
  • @GáborHéja: As I've written in my answer: you need to check the certificate inside the browser and this is not possible with Javascript. See the first two links I've provided. – Steffen Ullrich Jan 16 '20 at 17:35
0

Is there a way to detect in JavaScript if the site was loaded over HTTPS using an SSL certificate untrusted by the browser (but accepted by the user)? I.e. it is invalid/expired/self-signed SSL certificate.

Yes, it is possible, however it requires more than just JavaScript on the client.

You can setup a server that takes a https link and returns whether the certificate is valid. This way, by using a JavaScript fetch command you can verify whether or not the certificate is trusted/valid.

Ascari Gh
  • 3
  • 1
  • Thanks for the answer, however I would like to detect it in the browser alone. Also, it is possible that a site presents different certificate for different clients, also, it is possible that the server would not have access to the site the client visits (i.e. internal network, localhost, etc.) – Gábor Héja Jan 27 '20 at 11:58
  • I see, well I can tell you right now it is impossible with client-side JavaScript alone. If you want to keep it client-side, and, you don't mind the solution not being only JavaScript, then you may be able to use the almost-obsolete Flash or Java since they allow you to create a TCP socket on the client. This will give you access to the raw certificate where you will be able to validate it yourself. This is impossible with JavaScript alone because there is not way to create a TCP socket and probably never will be since it's a big security concern. – Ascari Gh Feb 25 '20 at 17:59