Chrome · Passwords › Passwords
CVE-2026-106220
Info Disclosure in Passwords (Passwords)
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
forcomponents/password_manager/core/browser/form_parsing/password_field_prediction.cc |
modified | |
TEST_Fcomponents/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc |
modified | |
TESTcomponents/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc |
modified |
Files Changed
components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cccomponents/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cccomponents/password_manager/core/browser/form_parsing/password_field_prediction.cc
Patch
From 5f51b75ab67ce3178ea5574884ed0a6a755590c9 Mon Sep 17 00:00:00 2001 From: Maria Kazinova <[email protected]> Date: Mon, 07 Sep 2026 06:10:17 -0700 Subject: [PATCH] [Passwords] Exclude standalone CVC and IBAN from credential parsing Map standalone CVC and IBAN field type groups to CredentialFieldType::kNonCredential in DeriveFromFieldType() and prioritize them in GetServerType(), ensuring passwords are not suggested or saved on standalone CVC and IBAN fields. Fixed: 534843648 Change-Id: I18deb0a8bc5fb17207928bbcf6b1b5bcd007a38d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8359691 Reviewed-by: Friedrich Hauser <[email protected]> Commit-Queue: Maria Kazinova <[email protected]> Cr-Commit-Position: refs/heads/main@{#1693308} --- diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc index 9403373..d3e24cc7 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc @@ -21,6 +21,7 @@ using autofill::FieldGlobalId; using autofill::FieldSignature; using autofill::FieldType; +using autofill::FieldTypeGroup; using autofill::FormData; using autofill::ToSafeFieldType; @@ -28,15 +29,24 @@ namespace { +// Returns true if `type` belongs to a payment-related group (credit cards, +// standalone CVC, or IBAN). +bool IsPaymentRelated(FieldType type) { + FieldTypeGroup group = GroupTypeOfFieldType(type); + return group == FieldTypeGroup::kCreditCard || + group == FieldTypeGroup::kStandaloneCvcField || + group == FieldTypeGroup::kIban; +} + FieldType GetServerType(const AutofillServerPrediction& prediction) { // The main server predictions is in `field.server_type()` but the server can // send additional predictions in `field.server_predictions()`. This function // chooses the relevant one for Password Manager predictions. - // 1. If there is credit card related prediction, return the prediction. + // 1. If there is a payment related prediction, return the prediction. for (const auto& server_predictions : prediction.server_predictions) { FieldType type = static_cast<FieldType>(server_predictions.type()); - if (GroupTypeOfFieldType(type) == autofill::FieldTypeGroup::kCreditCard) { + if (IsPaymentRelated(type)) { return type; } } @@ -55,7 +65,7 @@ } // namespace CredentialFieldType DeriveFromFieldType(FieldType type) { - if (GroupTypeOfFieldType(type) == autofill::FieldTypeGroup::kCreditCard) { + if (IsPaymentRelated(type)) { return CredentialFieldType::kNonCredential; } diff --git a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc index 01a2e8f..20731c4 100644 --- a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc @@ -1945,6 +1945,24 @@ }, { .description_for_logging = + "Server hints: CREDIT_CARD_STANDALONE_VERIFICATION_CODE.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = FormControlType::kInputText}, + {.form_control_type = FormControlType::kInputPassword, + .server_predicted_type = + autofill::CREDIT_CARD_STANDALONE_VERIFICATION_CODE, + .manual_generation_enabled = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = FormControlType::kInputPassword}, + }, + // The result should be trusted for more than just fallback, because + // the chosen password was not a suspected CVC. + .fallback_only = false, + }, + { + .description_for_logging = "Server hints: CREDIT_CARD_VERIFICATION_CODE on only password.", .fields = { @@ -1956,6 +1974,19 @@ }, }, { + .description_for_logging = + "Server hints: CREDIT_CARD_STANDALONE_VERIFICATION_CODE on only " + "password.", + .fields = + { + {.form_control_type = FormControlType::kInputText}, + {.form_control_type = FormControlType::kInputPassword, + .server_predicted_type = + autofill::CREDIT_CARD_STANDALONE_VERIFICATION_CODE, + .manual_generation_enabled = false}, + }, + }, + { .description_for_logging = "Name of 'verification_type' matches the " "CVC pattern, ignore that one.", .fields = @@ -1987,6 +2018,37 @@ }); } +// The parser should avoid identifying IBAN fields as passwords. +TEST_F(FormParserTest, IgnoreIbanFields) { + CheckTestData({ + { + .description_for_logging = "Server hints: IBAN_VALUE.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = FormControlType::kInputText}, + {.form_control_type = FormControlType::kInputPassword, + .server_predicted_type = autofill::IBAN_VALUE, + .manual_generation_enabled = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = FormControlType::kInputPassword}, + }, + .fallback_only = false, + }, + { + .description_for_logging = + "Server hints: IBAN_VALUE on only password.", + .fields = + { + {.form_control_type = FormControlType::kInputText}, + {.form_control_type = FormControlType::kInputPassword, + .server_predicted_type = autofill::IBAN_VALUE, + .manual_generation_enabled = false}, + }, + }, + }); +} + TEST_F(FormParserTest, ServerHintsForCvcFieldsOverrideAutocomplete) { CheckTestData({ { diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc index 91eb8cc7..a0867bab 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc @@ -73,6 +73,18 @@ PASSWORD, CREDIT_CARD_VERIFICATION_CODE, {CREDIT_CARD_VERIFICATION_CODE}}, + // standalone cvc in |additional_types| takes precedence. + {"standalone_cvc", + FormControlType::kInputPassword, + PASSWORD, + CREDIT_CARD_STANDALONE_VERIFICATION_CODE, + {CREDIT_CARD_STANDALONE_VERIFICATION_CODE}}, + // iban in |additional_types| takes precedence. + {"iban", + FormControlType::kInputPassword, + PASSWORD, + IBAN_VALUE, + {IBAN_VALUE}}, // `CREDIT_CARD_NUMBER` takes precedence over any credential related // types. {"cc-number", @@ -211,6 +223,9 @@ CredentialFieldType::kConfirmationPassword}, {"Credit card number", CREDIT_CARD_NUMBER, CredentialFieldType::kNonCredential}, + {"Standalone CVC", CREDIT_CARD_STANDALONE_VERIFICATION_CODE, + CredentialFieldType::kNonCredential}, + {"IBAN", IBAN_VALUE, CredentialFieldType::kNonCredential}, {"Not password", NOT_PASSWORD, CredentialFieldType::kNonCredential}, {"Not username", NOT_USERNAME, CredentialFieldType::kNonCredential}, {"OTP", ONE_TIME_CODE, CredentialFieldType::kNonCredential}, @@ -225,6 +240,13 @@ } } +TEST(FormPredictionsTest, DeriveFromFieldType_StandaloneCvcAndIbanSiblings) { + EXPECT_EQ(CredentialFieldType::kNonCredential, + DeriveFromFieldType(CREDIT_CARD_STANDALONE_VERIFICATION_CODE)); + EXPECT_EQ(CredentialFieldType::kNonCredential, + DeriveFromFieldType(IBAN_VALUE)); +} + // Tests that if |AutofillServerPrediction| has an override flag, it // will be propagated to |FormPredictions|. TEST(FormPredictionsTest, ConvertToFormPredictions_OverrideFlagPropagated) {
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
index 01a2e8f..20731c4 100644
--- a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
@@ -1945,6 +1945,24 @@
},
{
.description_for_logging =
+ "Server hints: CREDIT_CARD_STANDALONE_VERIFICATION_CODE.",
+ .fields =
+ {
+ {.role = ElementRole::USERNAME,
+ .form_control_type = FormControlType::kInputText},
+ {.form_control_type = FormControlType::kInputPassword,
+ .server_predicted_type =
+ autofill::CREDIT_CARD_STANDALONE_VERIFICATION_CODE,
+ .manual_generation_enabled = false},
+ {.role = ElementRole::CURRENT_PASSWORD,
+ .form_control_type = FormControlType::kInputPassword},
+ },
+ // The result should be trusted for more than just fallback, because
+ // the chosen password was not a suspected CVC.
+ .fallback_only = false,
+ },
+ {
+ .description_for_logging =
"Server hints: CREDIT_CARD_VERIFICATION_CODE on only password.",
.fields =
{
@@ -1956,6 +1974,19 @@
},
},
{
+ .description_for_logging =
+ "Server hints: CREDIT_CARD_STANDALONE_VERIFICATION_CODE on only "
+ "password.",
+ .fields =
+ {
+ {.form_control_type = FormControlType::kInputText},
+ {.form_control_type = FormControlType::kInputPassword,
+ .server_predicted_type =
+ autofill::CREDIT_CARD_STANDALONE_VERIFICATION_CODE,
+ .manual_generation_enabled = false},
+ },
+ },
+ {
.description_for_logging = "Name of 'verification_type' matches the "
"CVC pattern, ignore that one.",
.fields =
@@ -1987,6 +2018,37 @@
});
}
+// The parser should avoid identifying IBAN fields as passwords.
+TEST_F(FormParserTest, IgnoreIbanFields) {
+ CheckTestData({
+ {
+ .description_for_logging = "Server hints: IBAN_VALUE.",
+ .fields =
+ {
+ {.role = ElementRole::USERNAME,
+ .form_control_type = FormControlType::kInputText},
+ {.form_control_type = FormControlType::kInputPassword,
+ .server_predicted_type = autofill::IBAN_VALUE,
+ .manual_generation_enabled = false},
+ {.role = ElementRole::CURRENT_PASSWORD,
+ .form_control_type = FormControlType::kInputPassword},
+ },
+ .fallback_only = false,
+ },
+ {
+ .description_for_logging =
+ "Server hints: IBAN_VALUE on only password.",
+ .fields =
+ {
+ {.form_control_type = FormControlType::kInputText},
+ {.form_control_type = FormControlType::kInputPassword,
+ .server_predicted_type = autofill::IBAN_VALUE,
+ .manual_generation_enabled = false},
+ },
+ },
+ });
+}
+
TEST_F(FormParserTest, ServerHintsForCvcFieldsOverrideAutocomplete) {
CheckTestData({
{
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
index 91eb8cc7..a0867bab 100644
--- a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
@@ -73,6 +73,18 @@
PASSWORD,
CREDIT_CARD_VERIFICATION_CODE,
{CREDIT_CARD_VERIFICATION_CODE}},
+ // standalone cvc in |additional_types| takes precedence.
+ {"standalone_cvc",
+ FormControlType::kInputPassword,
+ PASSWORD,
+ CREDIT_CARD_STANDALONE_VERIFICATION_CODE,
+ {CREDIT_CARD_STANDALONE_VERIFICATION_CODE}},
+ // iban in |additional_types| takes precedence.
+ {"iban",
+ FormControlType::kInputPassword,
+ PASSWORD,
+ IBAN_VALUE,
+ {IBAN_VALUE}},
// `CREDIT_CARD_NUMBER` takes precedence over any credential related
// types.
{"cc-number",
@@ -211,6 +223,9 @@
CredentialFieldType::kConfirmationPassword},
{"Credit card number", CREDIT_CARD_NUMBER,
CredentialFieldType::kNonCredential},
+ {"Standalone CVC", CREDIT_CARD_STANDALONE_VERIFICATION_CODE,
+ CredentialFieldType::kNonCredential},
+ {"IBAN", IBAN_VALUE, CredentialFieldType::kNonCredential},
{"Not password", NOT_PASSWORD, CredentialFieldType::kNonCredential},
{"Not username", NOT_USERNAME, CredentialFieldType::kNonCredential},
{"OTP", ONE_TIME_CODE, CredentialFieldType::kNonCredential},
@@ -225,6 +240,13 @@
}
}
+TEST(FormPredictionsTest, DeriveFromFieldType_StandaloneCvcAndIbanSiblings) {
+ EXPECT_EQ(CredentialFieldType::kNonCredential,
+ DeriveFromFieldType(CREDIT_CARD_STANDALONE_VERIFICATION_CODE));
+ EXPECT_EQ(CredentialFieldType::kNonCredential,
+ DeriveFromFieldType(IBAN_VALUE));
+}
+
// Tests that if |AutofillServerPrediction| has an override flag, it
// will be propagated to |FormPredictions|.
TEST(FormPredictionsTest, ConvertToFormPredictions_OverrideFlagPropagated) {
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page