Open mfoltzgoogle opened 4 years ago
Possibly related to (or a specific issue in) Issue #13
I think this is yet another issue that can be addressed by providing QuicTransport endpoints with URLs associated with it. So if we add URL for #22 and #26, we would probably get CSP support for ~free.
Discussed on December 8, 2020 WebTransport WG meeting. Agreement to support CSP for the Web PKI case. Concerns over impact of fingerprint verification on CSP support.
@vasilvv to write text and reach out to webappsec to discuss some of the more complex cases.
So I think the answer for WebPKI-authenticated connections is fairly clear: we will check connect-src
for WebTransport connections.
For the connections that are anchored against a custom certificate, I can see a few approaches:
Sec-WebTransport-Allow-Custom-Certificates
, that would opt the website into using custom certificates, or somehow encode that into CSP.example.com
with certificate fingerprint 0x1234abcd
gets translated into example.com.domain-1234abcd.fpr.arpa
(I think @ekr proposed something among those lines a few years ago when I discussed that problem with him).The first approach has the advantage of being very simple, but less powerful, as it's just an all-or-nothing approach. The second approach lets developers control the specific fingerprints, but it does require us to do more work. Notably, I have no idea what the policies are wrt assigning .arpa
domain names, and what are all of the implications.
cc @mikewest since he expressed interest in this topic in the past.
cc @martinthomson and @DavidSchinazi as they probably know more about .arpa
The discussions on webrtc-src are relevant here: w3c/webappsec-csp#457
I would say that a binary toggle for "custom certificate allowed" is probably easier than otherwise. Reconciling that with the WebRTC control would be ideal. Devising a new means of identifying specific certificates, similar to script-src with nonces, seems like a stretch goal.
You might consider a webtransport-src rule that inherits from connect-src.
Meeting:
One addendum: just use a boolean flag ('fp') to turn custom certificate fingerprints on/off rather than devise a system for identifying specific fingerprints (do that later).
As I mentioned in one of the WebRTC threads, I think acting as if "obtaining the connection" failed is preferable as it gives more freedom to where implementations decide to enforce the policy and makes the API contract for developers simpler.
Seconding @annevk; we started enforcing on fetch()
and XHR by throwing in the constructor, and shifted towards failing the connection instead, as it unified behavior between initial requests and redirects. I don't think that specific thing is a problem for web transport, but I do think aligning the behavior between WT on the one hand and fetch()
on the other seems like the right way to go.
So a new way to reject the ready promise?
Assuming the description at https://w3c.github.io/webtransport/#webtransport-ready is correct, yes. Using the same exception you do now to reject on connection establishment failure. (fetch()
uses JavaScript's generic TypeError
for all this.)
@yutakahirano With https://github.com/w3c/webtransport/pull/367 merged can this be closed now, or was it left open for a reason?
My understanding of that PR is that we now link to CSP and that the details of how that policy works will be handled there. Is that right?
The interaction between custom certificates hasn't been resolved yet, IIRC.
Regarding the issue with custom certificates, I've been trying to figure the exact threat model for this issue. The model I currently have in my head is roughly: if an attacker can inject code into the webpage, and they can do active network attacks, then they can work around CSP policies (such as connect-src 'self'
) by establishing a connection to an allowed CSP origin but using custom certificate API to bypass the certificate check that would normally stop them. This is a fairly niche attack (due to the combination of those two prerequisites), but it's something we should still probably address.
A simple flag to control this was the approach we've agreed to last time we discussed this during a WG meeting, and I think it should be sufficient. We still need to figure out the placement and syntax for this; as a starting point, I am going to suggest adding a webtransport-no-certificate-hash
directive to CSP that has no arguments and that automatically blocks all WebTransport connections that use serverCertificateHash
argument. What do people think?
cc @martinthomson @mikewest
Alternatively, could we add an HTTP header to the extended CONNECT request that mentions whether custom certificates were configured by the client JavaScript? That way server implementations could be configured by default to abort if that header is present.
I'm a fan of a new 'certificate-hash' label for 'connect-src' and friends, which would be off by default and so cascade down naturally (being disabled automatically if CSP rules were in play).
I'm a fan of a new 'certificate-hash' label for 'connect-src' and friends, which would be off by default and so cascade down naturally (being disabled automatically if CSP rules were in play).
That would be a good approach, though I am not sure this is backwards-compatible, i.e. if a website sends connect-src certificate-hash
to a browser that does not recognize it, would that break the directive?
That form of compatibility is fairly simple. Under (my understanding of[^1]) the CSP extension model, new directive values can only be more permissive, so it is safe to ignore unknown values.
The sort of compatibility problem that concerns me is the one where we ship the capability, then attempt to retrofit CSP to it. There, sites will exist that use connect-src
(and derivatives) and certificate hashes successfully, so adding a special directive value to connect-src
will result in those sites suddenly breaking. This is the problem WebRTC had to deal with; the result being somewhat inelegant.
[^1]: The CSP spec is remarkably obtuse and lacking in basic explanatory text that might make it easy to answer this sort of question, so I'm going on inference.
Meeting:
Meeting:
connect-src 'certificate-hash'
Meeting:
@vasilvv did you have time to look over the CSP spec? Can we close this now?
Discussed this with @vasilvv offline, and it's not clear if the current state is sufficient or we need to add anything to the CSP spec. Maybe worth discussing at the next meeting.
Meeting:
From https://github.com/w3c/webtransport/issues/59#issuecomment-1056019468 it looked like we were almost home:
Meeting:
- People who use the custom certificates today in Chrome might be broken if we use
connect-src 'certificate-hash'
- Might be OK if we do it quickly.
@vasilvv do we still think connect-src 'certificate-hash'
might work here? Should we not just do that?
Meeting:
- People who use the custom certificates today in Chrome might be broken if we use connect-src 'certificate-hash'
Based on chrome status it doesn't seem too late to do this.
From my (limited) understanding of CSP keywords, we'd need to define the keyword's interaction with other sources:
Content-Security-Policy: connect-src 'certificate-hash' https://A.com https://B.com
Clearly, this would disallow
new WebTransport("https://C.com"); // C is not A or B
But would it also disallow
new WebTransport("https://C.com", {serverCertificateHashes: [{algorithm: "sha-256", value}]});
?
If there's security value in limiting connects to specific URLs even without Web PKI, then probably yes.
Even if we do limit use of serverCertificateHashes to those URLs (A and B), there's no way to limit it just to A (and still allow B with TLS). That would probably require an independent directive instead. Something like:
Content-Security-Policy: webtransport-certificate-hash https://A.com;
connect-src https://B.com;
Currently, data exchange capabilities that are exposed to the Web are restricted through CSP connect-src, which restricts which origins can be connected to through WebSockets, XHR, etc.