diff --git a/components/password_manager/core/browser/actor_login/internal/actor_login_credential_filler.cc b/components/password_manager/core/browser/actor_login/internal/actor_login_credential_filler.cc index 3d2ef1fd4d0a9..dbd6378eb851a 100644 --- a/components/password_manager/core/browser/actor_login/internal/actor_login_credential_filler.cc +++ b/components/password_manager/core/browser/actor_login/internal/actor_login_credential_filler.cc @@ -395,6 +395,23 @@ void ActorLoginCredentialFiller::FillAllEligibleFields( [](const PasswordFormManager* form_manager) { return !form_manager->GetDriver()->IsInPrimaryMainFrame(); }); + } else if (PasswordFormManager* signin_form_manager = + ActorLoginFormFinder::GetSigninFormManager(eligible_managers)) { + // The selected signin form lives in a subframe. Only fill into frames + // that are same-origin with the signin form's frame: PSL-matching causes + // every same-eTLD+1 sibling iframe to surface the identical store record + // in GetBestMatches(), so DoesStoredCredentialBelongToManager() cannot + // distinguish the user-approved frame from an attacker-controlled + // subdomain iframe. + const url::Origin signin_origin = + signin_form_manager->GetDriver()->GetLastCommittedOrigin(); + std::erase_if( + eligible_managers, + [&signin_origin](const PasswordFormManager* form_manager) { + return !form_manager->GetDriver() + ->GetLastCommittedOrigin() + .IsSameOriginWith(signin_origin); + }); } for (PasswordFormManager* manager : eligible_managers) {