Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-domain SSL handshake failure in Firefox using xhr, client-certificate

The setup is as follows:

  • Firefox (both 3.x and 4b) with properly set up and working certificates, including a client certificate.
  • Web page with an XMLHttpRequest() type of AJAX call to a different subdomain.
  • Custom web server in said subdomain accepting requests, reponding with a permissive Access-Control-Allow-Origin header and requiring client verification.

The problem is that Firefox aborts the request (well, that's what it says in firebug anyway) abruptly. Running the setup with openssl s_server instead hints that Firefox actually doesn't even send the client certificate:

140727260153512:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer
did not return a certificate:s3_srvr.c:2965:ACCEPT

The same exact setup works perfectly with Chrome, suggesting perhaps a bug in Firefox. However, performing the ajax call with a <script> element injected into the DOM seems to work as intended...

So, has anyone else run into this? Is it a bug? Any workarounds? Is there something obvious missing?

like image 373
nnevala Avatar asked Nov 24 '10 13:11

nnevala


2 Answers

Chiming in 5 years later probably isn't much help to the OP, but in case someone else has this issue in the future...

Firefox appears to not send the client certificate with a cross-origin XHR request by default. Setting withCredentials=true on the XHR instance resolved the issue for me. Note that I also did not see this problem with Chrome--only Firefox.

For more info see this Mozilla Dev Network blog post. In particular, the following statement:

By default, in cross-site XMLHttpRequest invocations, browsers will not send credentials. A specific flag has to be set on the XMLHttpRequest object when it is invoked.

like image 120
Clint Harris Avatar answered Sep 30 '22 11:09

Clint Harris


The reason injecting the script works as opposed to a simple XHR request is because of the Single Origin Policy. This would probably explain why Chrome allows the XHR but not FF; Chrome considers the subdomain part of the same origin, but FF does not.

Injecting scripts from other domains (which is what Google Analytics does) is allowed and one of the practices to handle this situation.

The way my team handles this situation is by making a request through a server-side proxy.

I would recommend using a server-side proxy if you can, but the script injection method works fine as long as the code is coming from a trusted source.

I also found this article which describes your situation.

like image 32
linusthe3rd Avatar answered Sep 30 '22 13:09

linusthe3rd