Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top