Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX calls to untrusted (self-signed) HTTPS fail silently

Tags:

I want to make AJAX calls to a secure server that uses a self-signed certificate. In the environment where my app is being used, this is fine -- I can provide the CA cert to users and have them install it before using the app. However, sometimes, a user tries to visit the app before installing the certs. In these cases, the app silently fails -- at least in Firefox (most common case of the problem), it appears that the call silently dies, without even firing off the error handler. FWIW, if the user visits an actual page on the server, they get a cert warning.

I could hack in a workaround -- say, make a heartbeat/ping request and set up a watchdog timer to see if the server responds in time -- but that seems, well, hacky. I'd prefer to be able to test the connection ahead of time. What's the "right" way to make sure the server you want to talk to has a trusted cert from within Javascript? If it makes any difference, I'm doing my AJAX requests via JQuery.

UPDATE: There's an awesome punchline here. Turns out, AJAX was not the problem at all. I was sure based on the symptoms that it was related to the self-signed certs, but the lack of AJAX error was disturbing, esp. given the spec linked to in the answer below. Another team member nailed it: the AJAX error handlers weren't firing off because JQuery was never loaded! We were including JQuery from another subdomain of our site, also hosted on HTTPS -- and users had added exceptions for ourService.example.com but not js.example.com. Apparently if you point a <script> tag at non-trusted secure connection, that fails silently as well.

{/headdesk}

like image 303
Coderer Avatar asked Dec 30 '10 19:12

Coderer


1 Answers

XMLHttpRequests (AJAX requests) are only permitted on same-origin servers. That means the scheme://host:port part of the target URL has to match that of the current document. According to the spec, you shouldn't even be allowed to make a request on the SSL URL from the non-SSL one.

The less hackish solution that I see is that you just force-redirect all users to the SSL site. That way they will be forced to see the certificate warning before any AJAX request can be made.

Note: The spec also says that in case of TLS handshake failure (which I assume this case falls under, in a way) it should throw a NETWORK_ERR (code 19) exception. You could try to catch the exception when initiating the AJAX request. Refer to the spec on error handling for more details.

like image 141
Seldaek Avatar answered Oct 01 '22 02:10

Seldaek