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 <kazinova@google.com>
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 <friedrichh@chromium.org>
Commit-Queue: Maria Kazinova <kazinova@google.com>
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