diff --git a/components/webauthn/core/browser/remote_validation.cc b/components/webauthn/core/browser/remote_validation.cc index ad2751a0b8db3..13f28e9b0ad22 100644 --- a/components/webauthn/core/browser/remote_validation.cc +++ b/components/webauthn/core/browser/remote_validation.cc @@ -72,6 +72,13 @@ std::unique_ptr RemoteValidation::Create( const std::string& relying_party_id, scoped_refptr url_loader_factory, base::OnceCallback callback) { + // Defence in depth: never allow a non-secure caller to be authorised via + // .well-known. Desktop callers already gate on this; iOS did not. + if (OriginAllowedToMakeWebAuthnRequests(caller_origin) != + ValidationStatus::kSuccess) { + std::move(callback).Run(ValidationStatus::kBadRelyingPartyId); + return nullptr; + } if (!url_loader_factory) { std::move(callback).Run(ValidationStatus::kBadRelyingPartyId); return nullptr; diff --git a/components/webauthn/ios/passkey_tab_helper.mm b/components/webauthn/ios/passkey_tab_helper.mm index 28c9d38949820..0a229d578891c 100644 --- a/components/webauthn/ios/passkey_tab_helper.mm +++ b/components/webauthn/ios/passkey_tab_helper.mm @@ -193,6 +193,14 @@ void PasskeyTabHelper::HandleGetRequestedEvent(web::WebFrame* web_frame, request_type == PasskeyRequestParams::RequestType::kModal); const url::Origin& origin = web_frame->GetSecurityOrigin(); + // Reject non-secure callers before any RP-ID processing. This mirrors + // //content WebAuthRequestSecurityChecker and closes the http:// bypass via + // .well-known related-origin validation. + if (OriginAllowedToMakeWebAuthnRequests(origin) != + ValidationStatus::kSuccess) { + DeferToRenderer(web_frame, passkey_request_id, request_type); + return; + } const std::string& rp_id = params.RpId(); if (!OriginIsAllowedToClaimRelyingPartyId(rp_id, origin)) { if (!PerformRemoteRpIdValidation( @@ -318,6 +326,14 @@ void PasskeyTabHelper::HandleCreateRequestedEvent( } const url::Origin& origin = web_frame->GetSecurityOrigin(); + // Reject non-secure callers before any RP-ID processing. This mirrors + // //content WebAuthRequestSecurityChecker and closes the http:// bypass via + // .well-known related-origin validation. + if (OriginAllowedToMakeWebAuthnRequests(origin) != + ValidationStatus::kSuccess) { + DeferToRenderer(web_frame, passkey_request_id, request_type); + return; + } const std::string& rp_id = params.RpId(); if (!OriginIsAllowedToClaimRelyingPartyId(rp_id, origin)) { if (!PerformRemoteRpIdValidation(