Add a preference to enable sending client certificates when Fetch's credentials mode would exclude them, even though the spec says not to
Categories
(Core :: Security: PSM, enhancement, P1)
Tracking
()
Tracking | Status | |
---|---|---|
firefox87 | --- | fixed |
People
(Reporter: jgoerzen, Assigned: jgoerzen)
References
(Blocks 1 open bug)
Details
(Keywords: dev-doc-complete, parity-chrome, Whiteboard: [psm-assigned])
Attachments
(5 files, 1 obsolete file)
Updated•6 years ago
|
Comment 1•6 years ago
|
||
Comment 3•6 years ago
|
||
Comment 4•6 years ago
|
||
Comment 5•6 years ago
|
||
Comment 7•5 years ago
|
||
How can we determine what load is opting into being anonymous that really shouldn't be anonymous? Maybe it's a CORS preflight?
Comment 8•5 years ago
|
||
Christoph - This is either DOM or Networking, as we don't know enough about the relevant specs to know where to look as to how this behavior is ... misbehaving. Can you weigh in, and if need be move it on to Networking or wherever it belongs?
Comment 9•5 years ago
|
||
Anne: this appears to be some clash between CORS (anonymous requests) and a site wanting to use Client certs. Haven't tested myself but the reporter claims Chrome works in this case. What ought to happen here? Sicking explicitly disabled this in bug 466080
Comment 10•5 years ago
|
||
This sounds like a duplicate of bug 1019603. Chrome's bug is https://bugs.chromium.org/p/chromium/issues/detail?id=775438.
Updated•5 years ago
|
Assignee | ||
Comment 12•4 years ago
|
||
Here is an updated diff, against Firefox 78.4.0esr.
Updated•4 years ago
|
Comment 13•4 years ago
|
||
Assignee | ||
Comment 14•4 years ago
|
||
Thank you, Dana! I'm wondering if anyone is able to help me out here or take over the patch? I really am not an expert on the Firefox codebase, and have never worked with that CORS code; I just wrote this one patch two years ago, and my time to plumb the depths is limited this week. I am of course happy to build and test whatever is developed and help in any way I can (including learning more about the internal CORS code when time permits) but just being realistic about my schedule right now. Thanks!
Updated•4 years ago
|
Comment 15•4 years ago
|
||
Dragana, can you help out here? The issue is that, from my reading, if this preference causes Firefox to unconditionally ignore the ANONYMOUS_CONNECT
flag, Firefox will send a client certificate in contexts other than just CORS preflights (private browsing, CSP reports, etc.). Is there a way to tell if a particular connection is for CORS?
Comment 16•4 years ago
|
||
We do not have a way to distinguish it it was CORS preflight request in PSM layer.
Way to go around this is to add a flag:
PSM reads nsISocketProvider flags, so we need to add a flag there. That flag should be set around here.
That means that we need to add similar flag to nsISocketTransport. nsISocketTransport flags are set here
...
And just looking into this there is a side affect of this:
we will need to isolate a connection that is used for CORS preflight and that means that connection will only be used for such requests, otherwise we will reuse it for other requests.
Maybe it is easier for a necko person to write the patch. I am happy to guide you jgoerzen if you like, but it will be a lot of details. Otherwise I will write a patch.
Assignee | ||
Comment 17•4 years ago
|
||
Please go ahead, Dragana. I'm not even a Firefox dev; I just learned enough about it to write the initial patch two years ago, so it would take quite a bit of time for me to get up to speed on all this. And THANK YOU!
Comment 18•4 years ago
|
||
Comment 19•4 years ago
|
||
This is only used for CORS preflight requests. It is controlled by a pref.
Connections that server such request will be isolated from other anonymous connections.
Comment 20•4 years ago
|
||
Hope this one is better:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=9040b76dd352ad3101a160d3a373963466a93366
Comment 21•4 years ago
|
||
Here the pref is off:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=5d9a4b99c228a11fc46fbc1e86e02b0b9604c764
With the pref turned on:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=b5d2879984d59915343cb4ce8777e8c62a3a065e
Comment 22•4 years ago
|
||
jgoerzen, do you want to try if this patch fixes your issue?
I am not sure on which platform you are but you can download a binary from the try run and just run it without installing anything. Of course you can delete the binary afterwords.
For linux, the build is:
https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/N_S8jWO2Sqa2ba8_ttEyZw/runs/0/artifacts/public/build/target.tar.bz2
Comment 23•4 years ago
|
||
You will need to type about:config in address bar and look network.cors_preflight.allow_client_cert and set it to true.
Assignee | ||
Comment 24•4 years ago
|
||
Hello,
I set that pref, loaded my cert, and unfortunately it didn't work.
I'd be happy to do whatever debugging I can to help with this.
- John
Comment 25•4 years ago
|
||
I remembered yesterday late evening that the flags are shared by 2 interfaces and that nsIRequest run out of flags. So flag that I set to be (1<<16) actually overlaps with another flag and messes all up. I need to think about how to resolved this, extending flags to be uint64_t will be a huge patch :(
Comment 26•4 years ago
|
||
Is it a major problem if the client certificate ends up being transmitted in other contexts? Even if we only did it for CORS preflights, that would still happen in private browsing mode, right? And any site could create a CORS preflight. If that's the simpler solution and this is off-by-default, maybe we should just go with that.
Comment 27•4 years ago
|
||
(In reply to Anne (:annevk) from comment #26)
Is it a major problem if the client certificate ends up being transmitted in other contexts? Even if we only did it for CORS preflights, that would still happen in private browsing mode, right? And any site could create a CORS preflight. If that's the simpler solution and this is off-by-default, maybe we should just go with that.
I would argue that that's a flaw in this patch, honestly. We should never send a client certificate in private browsing mode - that would be against the user's expectations.
Comment 28•4 years ago
|
||
Actually, I take that back - we currently already allow the user to choose to send client certificates in private browsing contexts (which I find a bit odd), so this patch doesn't change that behavior.
Assignee | ||
Comment 29•4 years ago
|
||
Hi, just checking to see where this is, and if I can help in any way. Thanks!
Comment 31•4 years ago
|
||
Ok, it looks like we may have a free bit for this flag.
https://treeherder.mozilla.org/#/jobs?repo=try&revision=e5292203839d465c5017263a0b2e23fa3a18011e
Comment 32•4 years ago
|
||
Assignee | ||
Comment 34•4 years ago
|
||
Gave it a try, verified network.cors_preflight.allow_client_cert is still true, verified my cert is imported, but it still didn't work, I'm afraid. Any debugging I can do to help out, just let me know.
Updated•4 years ago
|
Comment 35•4 years ago
|
||
Sorry for a late replay, I was on PTO.
Ok, I double checked the patch and it does what it suppose to do.
Maybe it is something else, not preflight that is set to be anonymous and therefore it does not get client certs.
Can you make me a log:
https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/HTTP_logging
please add ",pipnss:5" to MOZ_LOG
Thank you.
Assignee | ||
Comment 36•4 years ago
|
||
Hi,
Here is the log with the pipnss bits. If you need the log with the other components also, I do have that, but would like to find a less public way to share it with you.
Thanks,
John
Comment 37•4 years ago
|
||
I will need the other components as well. Can you send it via email?
Comment 38•4 years ago
|
||
I will look at the log to verify it, but it looks like allowing client certs only for preflights is not enough.
Anne and Dana, what do you think, can ve add a pref that allows client certs with LOAD_ANONYMOUS? It will be by default off.
Assignee | ||
Comment 39•4 years ago
|
||
Sent you an email with the rest of the log. Thanks!
Comment 40•4 years ago
|
||
I see, so they have code such as fetch(someCrossOriginURL, { ... })
and do not pass { credentials: "include" }
. As with CORS preflights it's not ideal to allow that, but I think for something that's disabled by default coupled with the fact that you need to have a client certificate configured which is very far from the norm, it's not too bad. And especially with Chrome not fixing their bug it's probably table stakes to at least offer this to enterprise users.
Comment 41•4 years ago
|
||
I'm not a fan of changing Firefox to contravene a specification, but I suppose since the de-facto standard (Chrome) doesn't seem interested in fixing this, then we don't have much of a choice.
Updated•4 years ago
|
Assignee | ||
Comment 42•4 years ago
|
||
In case it helps, here is my patch, updated against 78.7.0esr, that is solving it for me.
Comment 43•4 years ago
|
||
I'm a newcomer to this discussion, but I think I'm running into the same or similar bug:
- I do a cross-origin fetch with
{credentials: "include"}
. The method is PUT so this qualifies for requiring a preflight - the (cross-origin) server is configured to always require client certificates;
=> the server (nginx) reports "client sent no required SSL certificate while reading client request headers"
Also, I access the cross-origin server in a GET request prior to the PUT, so the 2-way TLS connection should already be up. Firefox seems to explicitly create a new one for the preflight and explicitly sends no client certificate.
User-Agent is "Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0", the server on another origin and requiring client certificates is nginx/1.18.0 with ssl_verify_client on
.
I can happily provide more details!
(I also saw the other bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1019603, but am not sure if that bug reports not prompting for a client certificate when {credentials: "include"}
is set, or when not.)
Comment 44•4 years ago
|
||
It's not a bug, but you're seeing the same issue. CORS preflights are supposed to never include credentials and servers that require credentials for successful CORS preflights are broken. Google Chrome unfortunately is also broken which is why we'll add an about:config
option for this. (Also adding this back on Dragana's queue.)
Comment 45•4 years ago
|
||
(In reply to Anne (:annevk) from comment #44)
It's not a bug, but you're seeing the same issue. CORS preflights are supposed to never include credentials and servers that require credentials for successful CORS preflights are broken. Google Chrome unfortunately is also broken which is why we'll add an
about:config
option for this. (Also adding this back on Dragana's queue.)
I've searched for info on this issue, so much of it is repetitive to you (sorry!), but: how come I need to make client certificates optional (to allow preflights) on my client-certificate-secured-server where I could simply tell from the provided certificate whether the client is allowed in or not?
From the way things are, I either can't enforce client certificates (seems strictly less secure, plus there is additional opportunity to not get the configuration right), or, I can be clever with the cross-origin requests and use POST with one of the allowed content types (but where really PUT would be the correct verb, and json the preferable content type).
What is there a attack vector we are protecting ourselves against/why are we doing this?
Comment 46•4 years ago
|
||
Cross-origin GET
/POST
with credentials without CORS preflight are legacy exceptions all servers have to deal with due to lack of a security model in the early days of the web. CORS preflights are not and to avoid them being used in a confused deputy attack or some such they do not carry credentials.
Comment 47•4 years ago
|
||
Can you try this build? You need to flip pref network.cors_preflight.allow_client_cert.
Comment 48•4 years ago
|
||
Comment 49•4 years ago
|
||
Comment 50•4 years ago
|
||
I forgot to pass a link....
This is the link to the build mentioned in comment #47.
https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/Of-AydMKQhKhXymMHhjXxg/runs/0/artifacts/public/build/target.tar.bz2
Comment 51•4 years ago
|
||
The Mac build worked for me.
Assignee | ||
Comment 52•4 years ago
|
||
That build worked for me. Excellent, thank you! I'm encouraged by this!
Comment 53•4 years ago
|
||
Updated•4 years ago
|
Comment 54•4 years ago
|
||
Comment 55•4 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/40dfa8a70d58
https://hg.mozilla.org/mozilla-central/rev/2ba77e4585c4
Comment 57•4 years ago
|
||
This is probably worthy of enterprise release notes for 87. No rush, but if someone gets a chance, can you do a release notes summary?
Comment 58•4 years ago
|
||
Mike, what exactly are you looking for? Something like this perhaps:
Corporations that use TLS client certificates can flip the
network.cors_preflight.allow_client_cert
preference to get Google Chrome-compatible handling of the CORS protocol. In particular, contrary to the Fetch Standard, this will transmit TLS client certificates along with a CORS preflight.
Updated•4 years ago
|
Comment 60•4 years ago
|
||
FYI, FF87 MDN docs for this added here: https://github.com/mdn/content/pull/2558
Essentially this is a new section under CORS > Requests with credentials (see here) that says you shouldn't send the credentials in preflight requests, then has a note saying - but you can if you need to using this preference.
Description
•