--- a/dom/u2f/U2F.cpp +++ b/dom/u2f/U2F.cpp @@ -30,16 +30,22 @@ public: namespace mozilla { namespace dom { static mozilla::LazyLogModule gU2FLog("u2fmanager"); NS_NAMED_LITERAL_STRING(kFinishEnrollment, "navigator.id.finishEnrollment"); NS_NAMED_LITERAL_STRING(kGetAssertion, "navigator.id.getAssertion"); +// Bug #1436078 - Permit Google Accounts. Remove in Bug #1436085 in Jan 2023. +NS_NAMED_LITERAL_STRING(kGoogleAccountsAppId1, + "https://www.gstatic.com/securitykey/origins.json"); +NS_NAMED_LITERAL_STRING(kGoogleAccountsAppId2, + "https://www.gstatic.com/securitykey/a/google.com/origins.json"); + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(U2F) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(U2F) NS_IMPL_CYCLE_COLLECTING_RELEASE(U2F) @@ -117,19 +123,25 @@ RegisteredKeysToScopedCredentialList(con } WebAuthnScopedCredential c; c.id() = keyHandle; aList.AppendElement(c); } } +enum class U2FOperation +{ + Register, + Sign +}; + static ErrorCode EvaluateAppID(nsPIDOMWindowInner* aParent, const nsString& aOrigin, - /* in/out */ nsString& aAppId) + const U2FOperation& aOp, /* in/out */ nsString& aAppId) { // Facet is the specification's way of referring to the web origin. nsAutoCString facetString = NS_ConvertUTF16toUTF8(aOrigin); nsCOMPtr<nsIURI> facetUri; if (NS_FAILED(NS_NewURI(getter_AddRefs(facetUri), facetString))) { return ErrorCode::BAD_REQUEST; } @@ -203,16 +215,25 @@ EvaluateAppID(nsPIDOMWindowInner* aParen MOZ_LOG(gU2FLog, LogLevel::Debug, ("AppId %s Facet %s", appIdHost.get(), lowestFacetHost.get())); if (html->IsRegistrableDomainSuffixOfOrEqualTo(NS_ConvertUTF8toUTF16(lowestFacetHost), appIdHost)) { return ErrorCode::OK; } + // Bug #1436078 - Permit Google Accounts. Remove in Bug #1436085 in Jan 2023. + if (aOp == U2FOperation::Sign && lowestFacetHost.EqualsLiteral("google.com") && + (aAppId.Equals(kGoogleAccountsAppId1) || + aAppId.Equals(kGoogleAccountsAppId2))) { + MOZ_LOG(gU2FLog, LogLevel::Debug, + ("U2F permitted for Google Accounts via Bug #1436085")); + return ErrorCode::OK; + } + return ErrorCode::BAD_REQUEST; } static nsresult BuildTransactionHashes(const nsCString& aRpId, const nsCString& aClientDataJSON, /* out */ CryptoBuffer& aRpIdHash, /* out */ CryptoBuffer& aClientDataHash) @@ -351,17 +372,18 @@ U2F::Register(const nsAString& aAppId, // Ensure we have a callback. if (NS_WARN_IF(!callback)) { return; } // Evaluate the AppID nsString adjustedAppId; adjustedAppId.Assign(aAppId); - ErrorCode appIdResult = EvaluateAppID(mParent, mOrigin, adjustedAppId); + ErrorCode appIdResult = EvaluateAppID(mParent, mOrigin, U2FOperation::Register, + adjustedAppId); if (appIdResult != ErrorCode::OK) { RegisterResponse response; response.mErrorCode.Construct(static_cast<uint32_t>(appIdResult)); ExecuteCallback(response, callback); return; } // Produce the AppParam from the current AppID @@ -513,17 +535,18 @@ U2F::Sign(const nsAString& aAppId, // Ensure we have a callback. if (NS_WARN_IF(!callback)) { return; } // Evaluate the AppID nsString adjustedAppId; adjustedAppId.Assign(aAppId); - ErrorCode appIdResult = EvaluateAppID(mParent, mOrigin, adjustedAppId); + ErrorCode appIdResult = EvaluateAppID(mParent, mOrigin, U2FOperation::Sign, + adjustedAppId); if (appIdResult != ErrorCode::OK) { SignResponse response; response.mErrorCode.Construct(static_cast<uint32_t>(appIdResult)); ExecuteCallback(response, callback); return; } // Produce the AppParam from the current AppID