From af4999cad584f16908f41325a19ef1a7e41c427e Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 1 Oct 2019 16:44:31 +0000 Subject: [PATCH] Bug 1383799 - Cancel WebAuthn operations on tab-switch r=ttaubert WebAuthn operations that are in-flight with authenticators must be cancelled when switching tabs. There's an Issue [1] opened with the WebAuthn spec for this already, but the language is _not_ in spec. Still, it's necessary for security, spec or not. This also matches how Chromium handles U2F operations during a tab switch. [1] https://github.com/w3c/webauthn/issues/316 MozReview-Commit-ID: 6Qh9oC4pqys UltraBlame original commit: f7a53ff2f8cb312eb6a65b127207e04d2bd1c79c --- dom/webauthn/WebAuthnManager.cpp | 366 ++++++++++++++++++++++++++++++- dom/webauthn/WebAuthnManager.h | 26 +++ 2 files changed, 388 insertions(+), 4 deletions(-) diff --git a/dom/webauthn/WebAuthnManager.cpp b/dom/webauthn/WebAuthnManager.cpp index c6bc7c9412860..d1689186c5bb7 100644 --- a/dom/webauthn/WebAuthnManager.cpp +++ b/dom/webauthn/WebAuthnManager.cpp @@ -631,10 +631,19 @@ webauthnmanager ) ; } +NS_NAMED_LITERAL_STRING +( +kVisibilityChange +" +visibilitychange +" +) +; NS_IMPL_ISUPPORTS ( WebAuthnManager nsIIPCBackgroundChildCreateCallback +nsIDOMEventListener ) ; / @@ -1217,6 +1226,11 @@ nsACString aHost ) { +MOZ_ASSERT +( +aParent +) +; nsCOMPtr < nsIDocument @@ -1755,6 +1769,169 @@ return NS_OK ; } +static +void +ListenForVisibilityEvents +( +nsPIDOMWindowInner +* +aParent +WebAuthnManager +* +aListener +) +{ +MOZ_ASSERT +( +aParent +) +; +MOZ_ASSERT +( +aListener +) +; +nsCOMPtr +< +nsIDocument +> +doc += +aParent +- +> +GetExtantDoc +( +) +; +if +( +NS_WARN_IF +( +! +doc +) +) +{ +return +; +} +nsresult +rv += +doc +- +> +AddSystemEventListener +( +kVisibilityChange +aListener +/ +* +use +capture +* +/ +true +/ +* +wants +untrusted +* +/ +false +) +; +Unused +< +< +NS_WARN_IF +( +NS_FAILED +( +rv +) +) +; +} +static +void +StopListeningForVisibilityEvents +( +nsPIDOMWindowInner +* +aParent +WebAuthnManager +* +aListener +) +{ +MOZ_ASSERT +( +aParent +) +; +MOZ_ASSERT +( +aListener +) +; +nsCOMPtr +< +nsIDocument +> +doc += +aParent +- +> +GetExtantDoc +( +) +; +if +( +NS_WARN_IF +( +! +doc +) +) +{ +return +; +} +nsresult +rv += +doc +- +> +RemoveSystemEventListener +( +kVisibilityChange +aListener +/ +* +use +capture +* +/ +true +) +; +Unused +< +< +NS_WARN_IF +( +NS_FAILED +( +rv +) +) +; +} / * * @@ -1942,6 +2119,22 @@ nullptr ; if ( +mCurrentParent +) +{ +StopListeningForVisibilityEvents +( +mCurrentParent +this +) +; +mCurrentParent += +nullptr +; +} +if +( mChild ) { @@ -2290,10 +2483,12 @@ within that range . -uint32_t +double adjustedTimeout = -30000 +30 +. +0 ; if ( @@ -2323,7 +2518,9 @@ std : max ( -15000u +15 +. +0 adjustedTimeout ) ; @@ -2334,7 +2531,9 @@ std : min ( -120000u +120 +. +0 adjustedTimeout ) ; @@ -3662,6 +3861,12 @@ Some info ) ; +ListenForVisibilityEvents +( +aParent +this +) +; return promise . @@ -3724,6 +3929,28 @@ ref ; } } +void +WebAuthnManager +: +: +StartCancel +( +) +{ +if +( +mChild +) +{ +mChild +- +> +SendRequestCancel +( +) +; +} +} already_AddRefed < Promise @@ -4715,6 +4942,12 @@ Some info ) ; +ListenForVisibilityEvents +( +aParent +this +) +; return promise . @@ -5943,6 +6176,13 @@ nsresult aError ) { +MOZ_ASSERT +( +NS_IsMainThread +( +) +) +; if ( mTransactionPromise @@ -5962,6 +6202,124 @@ MaybeClearTransaction ) ; } +NS_IMETHODIMP +WebAuthnManager +: +: +HandleEvent +( +nsIDOMEvent +* +aEvent +) +{ +MOZ_ASSERT +( +aEvent +) +; +nsAutoString +type +; +aEvent +- +> +GetType +( +type +) +; +if +( +! +type +. +Equals +( +kVisibilityChange +) +) +{ +return +NS_ERROR_FAILURE +; +} +nsCOMPtr +< +nsIDocument +> +doc += +do_QueryInterface +( +aEvent +- +> +InternalDOMEvent +( +) +- +> +GetTarget +( +) +) +; +MOZ_ASSERT +( +doc +) +; +if +( +doc +& +& +doc +- +> +Hidden +( +) +) +{ +MOZ_LOG +( +gWebAuthnManagerLog +LogLevel +: +: +Debug +( +" +Visibility +change +: +WebAuthn +window +is +hidden +cancelling +job +. +" +) +) +; +StartCancel +( +) +; +Cancel +( +NS_ERROR_ABORT +) +; +} +return +NS_OK +; +} void WebAuthnManager : diff --git a/dom/webauthn/WebAuthnManager.h b/dom/webauthn/WebAuthnManager.h index b901fe3ac57e2..75e0763112251 100644 --- a/dom/webauthn/WebAuthnManager.h +++ b/dom/webauthn/WebAuthnManager.h @@ -134,6 +134,17 @@ mozilla / dom / +Event +. +h +" +# +include +" +mozilla +/ +dom +/ PWebAuthnTransaction . h @@ -141,6 +152,13 @@ h # include " +nsIDOMEventListener +. +h +" +# +include +" nsIIPCBackgroundChildCreateCallback . h @@ -486,10 +504,13 @@ final : public nsIIPCBackgroundChildCreateCallback +public +nsIDOMEventListener { public : NS_DECL_ISUPPORTS +NS_DECL_NSIDOMEVENTLISTENER static WebAuthnManager * @@ -581,6 +602,11 @@ StartSign ( ) ; +void +StartCancel +( +) +; / / nsIIPCbackgroundChildCreateCallback