[whatwg/fetch] Clarification on CORS preflight fetches for TLS client certificates (#869)

TLS client certificates are included within CORS notion of [credentials](https://fetch.spec.whatwg.org/#credentials), for the reasons captured in [CORS protocol and credentials](https://fetch.spec.whatwg.org/#cors-protocol-and-credentials)

When considering cookies, it's sufficient to omit cookies from the request.
When considering HTTP auth, an attempt to request authentication (e.g. a 403 response) will be treated as a non-successful response status, and the CORS preflight will fail.

However, when considering TLS client certificates, there exists ambiguity in the processing model and expectation of the preflight. When the server/peer requests a client certificate, the client performing the CORS check has two possible options available to them:
1) Treat the server's CertificateRequest as equivalent to a 403 and fail the request
2) Treat the server's CertificateRequest as (possibly) optional, and attempt to continue the handshake without sending the peer a certificate, continuing the preflight check.

There are pros and cons to both methods, but the most notable one, which prompted this bug, is ambiguity in how server operators should configure mutual TLS authentication.

Generally, HTTP servers tend to offer at least three modes for client certificates - not configured, request (but don't require), or require. The difference in these latter two modes is that if it's set to "request (but don't require)", if the peer declines to send a certificate, that's generally passed up to the application layer to determine - for example, it might fail the request with an error code to indicate the user is not authenticated. However, the TLS session will have been considered successful, entered into TLS session caches, etc.

Alternatively, if they're set to "require", the server will fail the TLS handshake, preventing it from being added to any TLS session cache or otherwise reaching the application layer.

There's also a fourth mode, which is not valid in HTTP/2, which is "renegotiate". In this scenario, the request for a client certificate is not made during the initial TLS handshake. Instead, the server allows the peer to request the resource, and based on those request parameters, may have the application layer signal to the server layer that a TLS client certificate is expected. The server then sends a response to the client to initiate renegotiation, and during that renegotiation handshake, a client certificate is then requested and provided. This is banned from H2 and subsequent, due to the multiplexing at the application layer being incompatible with request-level authorization over the transport.

If the decision is that the CORS request should be aborted upon request for certificate, then it means that a server cannot use the request or require directives (and thus, not use H2), because any attempt to request a certificate during the initial handshake will cause CORS preflights to fail.

If the decision is that the CORS request should attempt to continue the handshake, without authentication, then user agents need to ensure that their [connection pool](https://fetch.spec.whatwg.org/#concept-connection-pool) is appropriately segmented, as the deliberate omission of the certificate may prevent the server from prompting, and the TLS session cache, if used, may prevent future attempts to authenticate.

In trying to determine how best to resolve the [Chromium spec-compliance bug](https://bugs.chromium.org/p/chromium/issues/detail?id=775438), we noted that it's ambiguous as to what the expectation is. **Our preference, which has considered feedback from Enterprises (including Google) that make heavy use of client certificates to protect and authenticate internal resources, is to continue the TLS handshake without sending a client certificate.**

However, that does mean that server operators deploying such technologies need to be aware that even though they are deploying client certificates to protect the resources, an improperly implemented CORS preflight may end up disclosing that there exist resources only visible to authenticated users.

Knowing that this area of Chromium's lack of spec compat has been a source of concern for Mozilla and Microsoft in the past, it would be great to know what they feel is appropriate, and great to capture this in the spec.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/869

Received on Wednesday, 6 February 2019 18:51:57 UTC