Open Bug 1019603 Opened 11 years ago Updated 8 months ago

TLS handshake fails on CORS preflight requests because no certificate is sent [per spec]

Categories

(Core :: Networking, defect, P3)

defect

Tracking

()

People

(Reporter: psotres, Unassigned)

References

Details

(Whiteboard: [necko-backlog])

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.132 Safari/537.36 OPR/21.0.1432.67 Steps to reproduce: Doing 2-way SSL auth on a CORS request. Actual results: The client certificate is not being sent to the server before doing the initial preflight request. As a result the TLS handshake fails and the OPTIONS request is aborted, hence the CORS request can't be performed. Using the same environment but running the Javascript request in the same origin (withouth the need of CORS) works as expected. In addition, if I keep using CORS but I disable SSL client auth at the server everything work as well. Expected results: The SSL client certificate should be sent in the TLS handshake, so the preflight OPTIONS request could be correctly sent.
Possible related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=566878 Comment: Nowhere in the CORS spec the fact that "The server has to be configured to accept non ssl preflight requests" is mentioned. Just some external related links that didn't seemed to be solved: https://stackoverflow.com/questions/4267379/cross-domain-ssl-handshake-failure-in-firefox-using-xhr-client-certificate https://stackoverflow.com/questions/10133497/cors-withcredentials-xhr-preflight-not-posting-cookies-in-firefox
Component: Untriaged → Networking
Product: Firefox → Core
I hit this same problem when trying to do CORS with client cert authentication configured on the remote server. The CORS preflight OPTIONS request is sent from FF w/o credentials as per the CORS spec. However, it appears that you can't setup JBoss to force client cert auth on some requests but not others. Given the wide-spread use of JBoss, it would be nice if there was a setting in FF to send credentials with CORS preflight messages. I'm not really sure what the rational is behind the CORS spec on this particular issue but I don't see the harm.
I can confirm this issue on Firefox 36.0.1 and nginx/1.4.6. Note that Chromium 39.0.2171.95 handles the issue while Firefox does not. Complete build identifier: Mozilla/5.0 (X11; Linux x86_64; rv:36.0) Gecko/20100101 Firefox/36.0
Hi This happens in a current project i am working on. Using Firefox Version 39. The preflight request to the (cross origin) server is not sent.My SSL expired and i renewed it. Still the preflight request is not sent. As a result the JSON Post call to the REST server is blocked by the browser. It works in other browsers safari and chrome.Copied all the parameters as curl for your reference. curl 'https://localhost:3000/api/v1/invoicesMetaData' -H 'Host: localhost:3000' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:39.0) Gecko/20100101 Firefox/39.0' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Referer: https://localhost:8080/SimpleReport' -H 'Content-Length: 217' -H 'Origin: https://localhost:8080' -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' Thanks Mahesh
Same issue here on a large project that intent to use firefox as default browser. This is a showstopper for us
We are experiencing the same issue both with IE and Firefox. Only Chrome seems to be working. Is there any update maybe or workaround? Thanks! PS. If of interest, the relevant IE bug is https://connect.microsoft.com/IE/feedback/details/1028302/ie11-cors-preflight-request-is-aborted-when-server-requests-client-tls-certificate.
what is the right thing to do here?
Flags: needinfo?(annevk)
Whiteboard: [necko-backlog]
Ryan, Takeshi, why does Chrome include credentials for a preflight request? (I should probably clarify https://fetch.spec.whatwg.org/#concept-connection-obtain with respect to client certificates. The intent has always been that when "credentials" are omitted, that includes client certificates, afaik.)
Flags: needinfo?(annevk)
Two possible answers: 1) There's a bug in Chrome, and we should fix. 2) They're using an enterprise policy which enables them to force-select a given client certificate for *all* requests for client certs that meet certain domain policies. I agree with Anne that the right thing to do is not send the client cert. I thought we had tests for that in Chrome, but if it really is working due to #1 and #2, that's our mistake.
I can still reproduce this issue in Firefox 49. My workflow is this: 1. AJAX GET request *with credentials* option to the same origin to get the redirect URL with all Access-Control-* headers to another site/port that requires a client certificate. 2. Once redirect is received with all control headers, Firefox always issues the OPTIONS request *but* does not prompt for (or send) a client certificate during this OPTIONS request and thus the request is rejected by IIS (403). Works in current versions of IE and Chrome, where a certificate is requested. Expected: Prompt for a certificate and/or directly executing the request hence all control headers are supplied.
The bug appears to still stay around. Ryan, ae you planning on fixing it?
Flags: needinfo?(ryan.sleevi)
I'm not sure what you're asking or why I was flagged.
Flags: needinfo?(ryan.sleevi)
Priority: -- → P1
Priority: P1 → P3
To be honest, I think the CORS spec should allow for credentials to be passed if the server asks for it. In the case of two-way SSL, wouldn't an un-authenticated OPTIONS request present a security risk? Perhaps this is why Chrome allows credentials to be passed in the preflight.
(In reply to ealexhaywood from comment #16) > To be honest, I think the CORS spec should allow for credentials to be > passed if the server asks for it. In the case of two-way SSL, wouldn't an > un-authenticated OPTIONS request present a security risk? Perhaps this is > why Chrome allows credentials to be passed in the preflight. Chrome Dev here responsible for the bug - and that’s definitely what it is, a bug, as we agree with the CORS spec and want to drop the ambient auth. I have the fix sketched out, but because of how low-level it is and how much would have to change, it’s lower on the priority to fix. It’s definitely not based on an intentional and thoughtful security analysis :)
Shouldn't the security risks be considered though? I understand it's in the spec, but allowing un-authenticated communication to a server configured for two-way SSL seems like an invitation for exploitation.
(In reply to ealexhaywood from comment #18) > Shouldn't the security risks be considered though? I understand it's in the > spec, but allowing un-authenticated communication to a server configured for > two-way SSL seems like an invitation for exploitation. They are being considered - the risk of reusing ambient auth for inter-origin communication introduces the confused deputy problem, hence the explicit assent by the destination server to allow the sending server to reuse those credentials. If you’re asking if there is risk in allowing TLS servers to negotiate both authenticated and unauthenticated sessions, no - not only is there not risk (if the server is actually based on the authentication state of the peer), but it results in an improved flow and experience for users lacking those credentials to understand why things are failing.
(In reply to Ryan Sleevi from comment #19) > [...] > If you’re asking if there is risk in allowing TLS > servers to negotiate both authenticated and unauthenticated sessions, no - > not only is there not risk (if the server is actually based on the > authentication state of the peer) [...] I think your parenthetical glosses over the problem from the server-side. As the current situation stands, supporting CORS preflight requests properly means it's impossible to require client certs at the TLS level (e.g, with httpd: SSLVerifyClient require; with nginx: ssl_verify_client on; etc.). Instead, client certificates have to be optional at the TLS level, which opens up the *previously secured* server to non-authenticated requests regardless of whether they are CORS preflight requests (which the server can't know until after it's negotiated TLS). Closing this hole introduces a new configuration burden, that of properly handling authenticated and unauthenticated requests at the HTTP rather than TLS level. For the common case of a reverse proxy, this configuration burden seems misplaced.
Summary: TLS handshake fails on CORS requests because no certificate is sent → TLS handshake fails on CORS requests because no certificate is sent [per spec]

Chrome seems to have put this in the permanent backlog and it continues to cause problems for users of Firefox, it might be time for another look.

Status: UNCONFIRMED → NEW
Webcompat Priority: --- → ?
Ever confirmed: true
OS: Windows 7 → All
Hardware: x86_64 → All
Version: 32 Branch → Trunk
Summary: TLS handshake fails on CORS requests because no certificate is sent [per spec] → TLS handshake fails on CORS preflight requests because no certificate is sent [per spec]

(In reply to Anne (:annevk) from comment #22)

Chrome seems to have put this in the permanent backlog and it continues to cause problems for users of Firefox, it might be time for another look.

That’s not correct. We just finished a major Chrome wide refactor to try and fix this, but had priorities shifted for the engineer leading this at the last moment. As the comment on the bug said, we’re incredibly close to fixing this, after changing how nearly every internal request was made.

(In reply to Ryan Sleevi from comment #23)

(In reply to Anne (:annevk) from comment #22)

Chrome seems to have put this in the permanent backlog and it continues to cause problems for users of Firefox, it might be time for another look.

That’s not correct. We just finished a major Chrome wide refactor to try and fix this, but had priorities shifted for the engineer leading this at the last moment. As the comment on the bug said, we’re incredibly close to fixing this, after changing how nearly every internal request was made.

Any updates on the timeline for fixing this?

Flags: needinfo?(ryan.sleevi)

I can't give a timeline for fixing this. The best way to engage is via https://bugs.chromium.org/p/chromium/issues/detail?id=775438

Flags: needinfo?(ryan.sleevi)

Dana, we will need to make a temporary change here until this is fixed in Chrome. There is a patch in bug 1511151. Can you find someone to finish it?

Flags: needinfo?(dkeeler)

Is there a reason this is particularly urgent now? If Chrome is fixing it, it seems like we should just wait and let them fix it.

Flags: needinfo?(dkeeler) → needinfo?(dd.mozilla)

(In reply to Dana Keeler (she/her) (use needinfo) (:keeler for reviews) from comment #27)

Is there a reason this is particularly urgent now? If Chrome is fixing it, it seems like we should just wait and let them fix it.

I am not sure when they are going to fix it. We can wait a bit, but I do not know how long. I will ask Anne to comment on this.

Flags: needinfo?(dd.mozilla) → needinfo?(annevk)

I agree that if Chrome ships a fix within a reasonable amount of time (say in a release build before August) we should probably hold the line, but there's enough indication at this point that this is making it hard to adopt Firefox in certain environments and as far as I'm aware it would not be a major change (even if it arguably is for the worse). (Unfortunately not all reported as bug reports.)

Edit: commented on the Chrome issue.

Flags: needinfo?(annevk)

Dana, how would you feel about adding the preference proposed in bug 1511151 for enterprise users affected by this? At least until Chrome removes support (I left another comment in the Chrome bug, but it's also been quite a while already).

Flags: needinfo?(dkeeler)

I suppose it wouldn't be worse than the preference we already have that automatically sends a client certificate to anyone who asks with a normal request.

Flags: needinfo?(dkeeler)

Thanks Dana, bug 1511151 comment 12 has a new patch, would you be able to review that and get it landed?

Flags: needinfo?(dkeeler)

I'll have a look.

Flags: needinfo?(dkeeler)

Hi, there are some review comments from Dana in #1511151 that are outside my experience with the Firefox codebase. I suspect it should be trivial for someone that knows their way around the CORS code. Would there by chance be anybody following this bug that would be able to take over that patch? I'm happy to build + test whatever is developed. Thank you!

Depends on: 1511151
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → DUPLICATE

I would prefer to keep this open since the network.cors_preflight.allow_client_cert preference is false and with Chrome not prioritizing fixing this we might have to consider flipping the preference. Hope that's okay.

Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Flags: needinfo?(james)

So the status here seems to be that we have a pref to enable the nonstandard behaviour, and chrome has a flag to enable the standard behaviour?

Given that we don't have public site breakge associated with this, and it's possible for enterprise users to work around the issue by setting a pref, I'm unsetting the webcompat-priority flag, but if we find out about specific sites that break when the pref is unset, please re-flag for triage.

Webcompat Priority: ? → ---
Flags: needinfo?(james)
Severity: normal → S3

It sounds like there's progress happening again at Google, though slowly.

Status: REOPENED → NEW
You need to log in before you can comment on or make changes to this bug.