There are two related problems this patch is trying to address. The first, and
simpler, one is bug 1553436: there are websites that use existing variables and
functions named "u2f" and adding a non-replaceable readonly property with that
name on Window breaks them. The fix for this is straightforward: mark the
property [Replaceable].
The second problem, covered by bug 1551282, involves sites that use the Google
U2F polyfill. The relevant parts of that polyfill look like this:
'use strict';
var u2f = u2f || {};
u2f.register = some_function_that_only_works_right_in_Chrome;
u2f.sign = some_function_that_only_works_right_in_Chrome;
The failure mode for that code before this fix is that the assignment to "u2f"
throws because it's a readonly property and we're in strict mode, so any code
the page concatenates in the same file after the polyfill does not get run.
That's what bug 1551282 is about. The [Replaceable] annotation fixes that
issue, because now the polyfill gets the value of window.u2f and then redefines
the property (via the [Replaceable] setter) to be a value property with that
value. So far, so good.
But then we need to prevent the sets of u2f.register
and u2f.sign from taking effect, because if they are allowed to happen, the
actual sign/register functionality on the page will not work in Firefox. We
can't just make the properties readonly, because then the sets will throw due
to being in strict mode, and we still have bug 1551282. The proposed fix is to
make these accessor properties with a no-op setter, which is exactly what
[LenientSetter] gives us.
The rest of the patch is just setting up infrastructure for generating the
normal bits we would generate if "sign" and "register" were methods and using
that to create the JSFunctions at the point when the getter is called. The
JSFunctions then get cached on the u2f instance object.
Differential Revision: https://phabricator.services.mozilla.com/D32357
--HG--
extra : moz-landing-system : lando
There are two related problems this patch is trying to address. The first, and
simpler, one is bug 1553436: there are websites that use existing variables and
functions named "u2f" and adding a non-replaceable readonly property with that
name on Window breaks them. The fix for this is straightforward: mark the
property [Replaceable].
The second problem, covered by bug 1551282, involves sites that use the Google
U2F polyfill. The relevant parts of that polyfill look like this:
'use strict';
var u2f = u2f || {};
u2f.register = some_function_that_only_works_right_in_Chrome;
u2f.sign = some_function_that_only_works_right_in_Chrome;
The failure mode for that code before this fix is that the assignment to "u2f"
throws because it's a readonly property and we're in strict mode, so any code
the page concatenates in the same file after the polyfill does not get run.
That's what bug 1551282 is about. The [Replaceable] annotation fixes that
issue, because now the polyfill gets the value of window.u2f and then redefines
the property (via the [Replaceable] setter) to be a value property with that
value. So far, so good.
But then we need to prevent the sets of u2f.register
and u2f.sign from taking effect, because if they are allowed to happen, the
actual sign/register functionality on the page will not work in Firefox. We
can't just make the properties readonly, because then the sets will throw due
to being in strict mode, and we still have bug 1551282. The proposed fix is to
make these accessor properties with a no-op setter, which is exactly what
[LenientSetter] gives us.
The rest of the patch is just setting up infrastructure for generating the
normal bits we would generate if "sign" and "register" were methods and using
that to create the JSFunctions at the point when the getter is called. The
JSFunctions then get cached on the u2f instance object.
Differential Revision: https://phabricator.services.mozilla.com/D32357
--HG--
extra : moz-landing-system : lando
Before this patch, the WebAuthnManager/U2F destructors would call MaybeReject on
existing transaction promises. Doing this leaks JS objects. If
WebAuthnManager/U2F are being destructed, though, the window is going away, so
it shouldn't be necessary to reject any outstanding promises. This patch just
clears the transactions.
Differential Revision: https://phabricator.services.mozilla.com/D27346
--HG--
extra : moz-landing-system : lando
This stack is pretty clear that calling StopListeningForVisibilityEvents
(via ClearTransaction) is a no-go from the cycle collector. We need to instead
just do the minimum version of bug 1540378, just reset mTransaction and move on.
Differential Revision: https://phabricator.services.mozilla.com/D25804
--HG--
extra : moz-landing-system : lando
In Bug 1448408 ("Don't listen to visibility events"), it became possible to
close a tab without a visibility event to cause transactions to cancel. This
is a longstanding bug that was covered up by the visibility events. This patch
updates the cycle collection code to ensure that transactions get cleared out
safely, and we don't proceed to RejectTransaction (and subsequent code) on
already-cycle-collected objects.
Differential Revision: https://phabricator.services.mozilla.com/D25641
--HG--
extra : moz-landing-system : lando
The published recommendation of L1 for WebAuthn changed the visibility/focus
listening behaviors to a SHOULD [1], and Chromium, for reasons like our SoftU2F
bug [0], opted to not interrupt on tabswitch/visibility change.
Let's do the same thing.
This changes the visibility mechanism to set a flag on an ongoing transaction,
and then, upon multiple calls to the FIDO/U2F functions, only aborts if
visibility had changed. Otherwise, subsequent callers return early.
This is harder to explain than it is really to use as a user. I think. At least,
my testing feels natural when I'm working within two windows, both potentially
prompting WebAuthn.
Note: This also affects FIDO U2F API.
[0] https://bugzilla.mozilla.org/show_bug.cgi?id=1448408#c0
[1] https://www.w3.org/TR/webauthn-1/#abortoperation
Differential Revision: https://phabricator.services.mozilla.com/D25160
--HG--
extra : moz-landing-system : lando
Per the thread "Intent-to-Ship: Backward-Compatibility FIDO U2F support for
Google Accounts" on dev-platform [0], this bug is to:
1. Enable the security.webauth.u2f by default, to ride the trains
2. Remove the aOp == U2FOperation::Sign check from EvaluateAppID in
WebAuthnUtil.cpp, permitting the Google override to work for Register as
well as Sign.
This would enable Firefox users to use FIDO U2F API on most all sites, subject
to the algorithm limitations discussed in the section "Thorny issues in
enabling our FIDO U2F API implementation" of that post.
[0] https://groups.google.com/d/msg/mozilla.dev.platform/q5cj38hGTEA/lC834665BQAJ
Differential Revision: https://phabricator.services.mozilla.com/D25241
--HG--
extra : moz-landing-system : lando
The old code for member method calls did the following:
1) Find the member method calls.
2) Look at their "this" expression.
3) If the "this" is an operator call, check for any of the arguments of the
operator call being invalid.
4) Otherwise (if not an operator call) check for the "this" value being
invalid.
This wasn't right, because the "is invalid" check checks the type and only
considers refcounted things. So if the code looked something like
"foo[i]->call_method()", we would look at the types of "foo" and "i" and
determine that none of those are refcounted types so there is nothing invalid
here (since "foo" is some sort of array type and "i" is an integer). The new
setup just checks whether the "this" value is invalid, which does the type
check on the "this" value itself; in the "foo[i]->call_method()" case on
"foo[i]". We then adjust the exclusions in InvalidArg to consider operator->
on known-live things valid, to allow the thing that we were really trying to
accomplish with the "check for an operator call" bits:
"stackRefPtr->some_method()".
The test coverage being added for the made-up TArray type is meant to catch
things like the geolocation issue that was being hidden by the buggy behavior.
I'm not using nsTArray itself because some header included by nsTArray.h
tries to define operator new/delete bits inline and that triggers warnings that
then cause a clang-plugin test failure, because they're unexpected.
Differential Revision: https://phabricator.services.mozilla.com/D24117
--HG--
extra : moz-landing-system : lando
The old code for member method calls did the following:
1) Find the member method calls.
2) Look at their "this" expression.
3) If the "this" is an operator call, check for any of the arguments of the
operator call being invalid.
4) Otherwise (if not an operator call) check for the "this" value being
invalid.
This wasn't right, because the "is invalid" check checks the type and only
considers refcounted things. So if the code looked something like
"foo[i]->call_method()", we would look at the types of "foo" and "i" and
determine that none of those are refcounted types so there is nothing invalid
here (since "foo" is some sort of array type and "i" is an integer). The new
setup just checks whether the "this" value is invalid, which does the type
check on the "this" value itself; in the "foo[i]->call_method()" case on
"foo[i]". We then adjust the exclusions in InvalidArg to consider operator->
on known-live things valid, to allow the thing that we were really trying to
accomplish with the "check for an operator call" bits:
"stackRefPtr->some_method()".
The test coverage being added for the made-up TArray type is meant to catch
things like the geolocation issue that was being hidden by the buggy behavior.
I'm not using nsTArray itself because some header included by nsTArray.h
tries to define operator new/delete bits inline and that triggers warnings that
then cause a clang-plugin test failure, because they're unexpected.
Differential Revision: https://phabricator.services.mozilla.com/D24117
--HG--
extra : moz-landing-system : lando
Summary: Really sorry for the size of the patch. It's mostly automatic
s/nsIDocument/Document/ but I had to fix up in a bunch of places manually to
add the right namespacing and such.
Overall it's not a very interesting patch I think.
nsDocument.cpp turns into Document.cpp, nsIDocument.h into Document.h and
nsIDocumentInlines.h into DocumentInlines.h.
I also changed a bunch of nsCOMPtr usage to RefPtr, but not all of it.
While fixing up some of the bits I also removed some unneeded OwnerDoc() null
checks and such, but I didn't do anything riskier than that.
This was done automatically replacing:
s/mozilla::Move/std::move/
s/ Move(/ std::move(/
s/(Move(/(std::move(/
Removing the 'using mozilla::Move;' lines.
And then with a few manual fixups, see the bug for the split series..
MozReview-Commit-ID: Jxze3adipUh
Summary:
FIDO U2F's specification says that when the wrong security key responds to a
signature, or when an already-registered key exists, that the UA should return
error code 4, DEVICE_INELIGIBLE. We used to do that, but adjusted some things
for WebAuthn and now we don't. This changes the soft token to return that at
the appropriate times, and updates the expectations of U2F.cpp that it should
use InvalidStateError as the signal to reutrn DEVICE_INELIGIBLE.
Also, note that WebAuthn's specification says that if any authenticator returns
"InvalidStateError" that it should be propagated, as it indicates that the
authenticator obtained user consent and failed to complete its job [1].
This change to the Soft Token affects the WebAuthn tests, but in a good way.
Reading the WebAuthn spec, we should not be returning NotAllowedError when there
is consent from the user via the token (which the softtoken always deliveres).
As such, this adjusts the affected WebAuthn tests, and adds a couple useful
checks to test_webauthn_get_assertion.html for future purposes.
[1] https://w3c.github.io/webauthn/#createCredential section 5.1.3 "Create a new
credential", Step 20, Note 2: "If any authenticator returns an error status
equivalent to "InvalidStateError"..."
Test Plan: https://treeherder.mozilla.org/#/jobs?repo=try&revision=f2fc930f7fc8eea69b1ebc96748fe95e150a92a4
Reviewers: ttaubert
Bug #: 1460767
Differential Revision: https://phabricator.services.mozilla.com/D1269
--HG--
extra : transplant_source : M%5B%93%81%29%7E%B2%E8%24%05%A6%96%8BUN%C9%FB%3E%B3h
This patch support already-enrolled U2F devices at Google Accounts by adding a
hard-coded "OK" into the U2F EvaluateAppID method, per the intent-to-ship [1].
This adds no tests, as this is not testable in our infrastructure. It will
require cooporation with Google Accounts to validate.
[1] https://groups.google.com/d/msg/mozilla.dev.platform/Uiu3fwnA2xw/201ynAiPAQAJ
MozReview-Commit-ID: 1YLd5sfeTKv
--HG--
extra : rebase_source : 96bfb92819be2c6e549dae0a5df0525587f894b8
This patch support already-enrolled U2F devices at Google Accounts by adding a
hard-coded "OK" into the U2F EvaluateAppID method, per the intent-to-ship [1].
This adds no tests, as this is not testable in our infrastructure. It will
require cooporation with Google Accounts to validate.
[1] https://groups.google.com/d/msg/mozilla.dev.platform/Uiu3fwnA2xw/201ynAiPAQAJ
MozReview-Commit-ID: 1YLd5sfeTKv
--HG--
extra : rebase_source : bfdb407cec61c4f4e5efaf85d1590fe287aaea4c
Summary:
Add support for PublicKeyCredentialRequestOptions.userVerification. For now
this basically means that we'll abort the operation with NotAllowed, as we
don't support user verification yet.
Pass PublicKeyCredentialDescriptor.transports through to the token manager
implementations. The softoken will ignore those and pretend to support all
transports defined by the spec. The USB HID token will check for the "usb"
transport and either ignore credentials accordingly, or abort the operation.
Note: The `UserVerificationRequirement` in WebIDL is defined at https://w3c.github.io/webauthn/#assertion-options
Reviewers: jcj, smaug
Reviewed By: jcj, smaug
Bug #: 1406467
Differential Revision: https://phabricator.services.mozilla.com/D338
--HG--
extra : amend_source : 314cadb3bc40bbbee2a414bc5f13caed55f9d720
Summary:
Ensure that transactions are cleared before U2FCallbacks are called, to allow
reentrancy from microtask checkpoints.
Move the two possible callbacks into U2FTransaction so we have nicer invariants
and know that there's a callback as long as we have a transaction.
Reviewers: jcj
Reviewed By: jcj
Bug #: 1422661
Differential Revision: https://phabricator.services.mozilla.com/D329
--HG--
extra : amend_source : 7097f38199a5bc4a215377e4f1a64079cf6d6a24
Summary: We can probably abstract more stuff in the future, but this seems like a good start.
Reviewers: jcj
Reviewed By: jcj
Bug #: 1396907
Differential Revision: https://phabricator.services.mozilla.com/D323
Summary:
We currently have a single WebAuthnManager instance per process that's shared
between all CredentialContainers. That way the nsPIDOMWindowInner parent has
to be tracked by the transaction, as multiple containers could kick off
requests simultaneously.
This patch lets us we have one WebAuthnManager instance per each
CredentialsContainer and thus each nsPIDOMWindowInner. This matches the current
U2F implementation where there is one instance per parent window too.
This somewhat simplifies the communication diagram (at least in my head), as
each U2F/WebAuthnManager instance also has their own TransactionChild/Parent
pair for IPC protocol communication. The manager and child/parent pair are
destroyed when the window is.
Reviewers: jcj
Reviewed By: jcj
Bug #: 1421616
Differential Revision: https://phabricator.services.mozilla.com/D305
Summary:
We currently have a single WebAuthnManager instance per process that's shared
between all CredentialContainers. That way the nsPIDOMWindowInner parent has
to be tracked by the transaction, as multiple containers could kick off
requests simultaneously.
This patch lets us we have one WebAuthnManager instance per each
CredentialsContainer and thus each nsPIDOMWindowInner. This matches the current
U2F implementation where there is one instance per parent window too.
This somewhat simplifies the communication diagram (at least in my head), as
each U2F/WebAuthnManager instance also has their own TransactionChild/Parent
pair for IPC protocol communication. The manager and child/parent pair are
destroyed when the window is.
Reviewers: jcj
Reviewed By: jcj
Bug #: 1421616
Differential Revision: https://phabricator.services.mozilla.com/D305
This was automatically generated by the script modeline.py.
MozReview-Commit-ID: BgulzkGteAL
--HG--
extra : rebase_source : a4b9d16a4c06c4e85d7d85f485221b1e4ebdfede
Summary:
This patch aims to clean up the U2FManager's state machine, especially to make
cancellation of transactions clearer. To fix bug 1403818, we'll have to later
introduce a unique id that is forwarded to the U2FTokenManager.
There are multiple stages of cancellation/cleanup after a transaction was
started. All of the places where we previously called Cancel() or
MaybeClearTransaction() are listed below:
[stage 1] ClearTransaction
This is the most basic stage, we only clean up what information we have about
the current transaction. This means that the request was completed successfully.
It is used at the end of FinishRegister() and FinishSign().
[stage 2] RejectTransaction
The second stage will reject the transaction promise we returned to the caller.
Then it will call ClearTransaction, i.e. stage 1. It is used when one of the
two Finish*() functions aborts before completion, or when the parent process
sends a RequestAborted message.
[stage 2b] MaybeRejectTransaction
This is the same as stage 2, but will only run if there's an active transaction.
It is used by ~U2FManager() to reject and clean up when we the manager goes
away.
[stage 3] CancelTransaction
The third stage sends a "Cancel" message to the parent process before rejecting
the transaction promise (stage 2) and cleaning up (stage 1). It's used by
HandleEvent(), i.e. the document becomes inactive.
[stage 3b] MaybeCancelTransaction
This is the same as stage 3, but will only run if there's an active transaction.
It is used at the top of Register() and Sign() so that any active transaction
is cancelled before we handle a new request. It's also used by U2F::Cancel()
as long as bug 1410346 isn't fixed.
Reviewers: jcj
Reviewed By: jcj
Bug #: 1410345
Differential Revision: https://phabricator.services.mozilla.com/D144
In Comment 8 of Bug 1244959 [1], Brad Hill argues that instead of leaving our
U2F Facet support completely half-way, that we could use the Public Suffix logic
introduced into HTML for W3C Web Authentication (the method named
IsRegistrableDomainSuffixOfOrEqualTo) to scope the FIDO AppID to an eTLD+1
hierarchy. This is a deviation from the FIDO specification, but doesn't break
anything that currently works with our U2F implementation, and theoretically
enables sites that otherwise need an external FacetID fetch which we aren't
implementing.
The downside to this is that it's then Firefox-specific behavior. But since this
isn't a shipped feature, we have more room to experiment. As an additional
bonus, it encourages U2F sites to use the upcoming Web Authentication security
model, which will help them prepare to adopt the newer standard.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1244959#c8
MozReview-Commit-ID: DzNVhHT9qRL
--HG--
extra : rebase_source : 262e2ddbec325e0391d346473f27ae2738490da1