Bug 1981587 - avoid showing multiple attestation consent prompts. a=RyanVM

Original Revision: https://phabricator.services.mozilla.com/D265363

Differential Revision: https://phabricator.services.mozilla.com/D266839
This commit is contained in:
John M. Schanck
2025-10-01 00:23:34 +00:00
committed by rvandermeulen@mozilla.com
parent 6263dedb03
commit 933f621238
5 changed files with 32 additions and 5 deletions

View File

@@ -54,6 +54,13 @@ WebAuthnRegisterResult::GetAttestationObject(
return NS_OK;
}
NS_IMETHODIMP
WebAuthnRegisterResult::GetAttestationConsentPromptShown(
bool* aAttestationConsentPromptShown) {
*aAttestationConsentPromptShown = mAttestationConsentPromptShown;
return NS_OK;
}
NS_IMETHODIMP
WebAuthnRegisterResult::GetCredentialId(nsTArray<uint8_t>& aCredentialId) {
aCredentialId.Assign(mCredentialId);

View File

@@ -38,7 +38,8 @@ class WebAuthnRegisterResult final : public nsIWebAuthnRegisterResult {
const Maybe<bool>& aPrfSupported,
const Maybe<nsTArray<uint8_t>>& aPrfFirst,
const Maybe<nsTArray<uint8_t>>& aPrfSecond)
: mClientDataJSON(aClientDataJSON),
: mAttestationConsentPromptShown(false),
mClientDataJSON(aClientDataJSON),
mCredPropsRk(Nothing()),
mAuthenticatorAttachment(aAuthenticatorAttachment),
mLargeBlobSupported(aLargeBlobSupported),
@@ -63,6 +64,7 @@ class WebAuthnRegisterResult final : public nsIWebAuthnRegisterResult {
reinterpret_cast<uint8_t*>(
aResponse->AttestationObject()->GetElements().Elements()),
aResponse->AttestationObject()->Length());
mAttestationConsentPromptShown = false;
if (aResponse->ClientDataJson()) {
mClientDataJSON = Some(nsAutoCString(
reinterpret_cast<const char*>(
@@ -92,6 +94,7 @@ class WebAuthnRegisterResult final : public nsIWebAuthnRegisterResult {
mAttestationObject.AppendElements(aResponse->pbAttestationObject,
aResponse->cbAttestationObject);
mAttestationConsentPromptShown = true;
nsTArray<WebAuthnExtensionResult> extensions;
if (aResponse->dwVersion >= WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2) {
@@ -166,6 +169,7 @@ class WebAuthnRegisterResult final : public nsIWebAuthnRegisterResult {
~WebAuthnRegisterResult() = default;
nsTArray<uint8_t> mAttestationObject;
bool mAttestationConsentPromptShown;
nsTArray<uint8_t> mCredentialId;
nsTArray<nsString> mTransports;
Maybe<nsCString> mClientDataJSON;

View File

@@ -115,10 +115,18 @@ WebAuthnService::MakeCredential(uint64_t aTransactionId,
}
nsIWebAuthnRegisterResult* result = aValue.ResolveValue();
// If the RP requested attestation, we need to show a consent prompt
// before returning any identifying information. The platform may
// have already done this for us, so we need to inspect the
// attestation object at this point.
// We can return whatever result we have if the authenticator
// handled attestation consent for us.
bool attestationConsentPromptShown = false;
Unused << result->GetAttestationConsentPromptShown(
&attestationConsentPromptShown);
if (attestationConsentPromptShown) {
guard->ref().parentRegisterPromise.ref()->Resolve(result);
guard->reset();
return;
}
// If the RP requested attestation and the response contains
// identifying information, then we need to show a consent prompt.
bool resultIsIdentifying = true;
Unused << result->HasIdentifyingAttestation(&resultIsIdentifying);
if (attestationRequested && resultIsIdentifying) {
@@ -127,6 +135,7 @@ WebAuthnService::MakeCredential(uint64_t aTransactionId,
aBrowsingContextId);
return;
}
// In all other cases we strip out identifying information.
result->Anonymize();
guard->ref().parentRegisterPromise.ref()->Resolve(result);
guard->reset();

View File

@@ -185,6 +185,11 @@ impl WebAuthnRegisterResult {
Ok(out)
}
xpcom_method!(get_attestation_consent_prompt_shown => GetAttestationConsentPromptShown() -> bool);
fn get_attestation_consent_prompt_shown(&self) -> Result<bool, nsresult> {
Ok(false)
}
xpcom_method!(get_credential_id => GetCredentialId() -> ThinVec<u8>);
fn get_credential_id(&self) -> Result<ThinVec<u8>, nsresult> {
let Some(credential_data) = &self.result.borrow().att_obj.auth_data.credential_data else {

View File

@@ -15,6 +15,8 @@ interface nsIWebAuthnRegisterResult : nsISupports {
// the authenticator data.
readonly attribute Array<octet> attestationObject;
readonly attribute boolean attestationConsentPromptShown;
// The Credential ID field of the Attestation Object's Attested
// Credential Data. This is used to construct the rawID field of a
// WebAuthn PublicKeyCredential without having to parse the