Chrome · Transactions Platform
CVE-2026-87490
Logic Error in Transactions Platform
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifcomponents/autofill/core/browser/data_model/payments/iban.cc |
modified |
Files Changed
components/autofill/core/browser/data_model/payments/iban.cc
Patch
From 43e38fad912ec6436cacda32d6b90b0ffd14e5bb Mon Sep 17 00:00:00 2001
From: Gianmarco Picarella <picarella@google.com>
Date: Mon, 10 Aug 2026 03:42:02 -0700
Subject: [PATCH] Fix IBAN validation regex and unify validation logic
Fixes IBAN validation by aligning the regex with the ISO 13616 standard
and replaces duplicate validation helpers with `Iban::IsValid()`.
Changes:
- Update IBAN regex, removing the broken `[0-9]{7}` restriction that
failed for KZ, RO, and LC.
- Remove `IsInternationalBankAccountNumber()` and its regex constant in
favor of `Iban::IsValid()`.
- Update `Iban::IsValid()` to accept `std::u16string_view`.
- Add support for Norway (NO, length 15).
- Add unit tests covering KZ, RO, LC, NO, and other countries.
Fixed: 533112829
Change-Id: Id08f724ea925a6dc634fbefacbf50d90512c729a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8226265
Reviewed-by: Jihad Hanna <jihadghanna@google.com>
Commit-Queue: Gianmarco Picarella <picarella@google.com>
Cr-Commit-Position: refs/heads/main@{#1676334}
---
diff --git a/components/autofill/core/browser/data_model/payments/iban.cc b/components/autofill/core/browser/data_model/payments/iban.cc
index 9ed93726..8b0cdb19 100644
--- a/components/autofill/core/browser/data_model/payments/iban.cc
+++ b/components/autofill/core/browser/data_model/payments/iban.cc
@@ -15,6 +15,8 @@
#include "base/check.h"
#include "base/check_op.h"
+#include "base/containers/fixed_flat_map.h"
+#include "base/containers/map_util.h"
#include "base/i18n/case_conversion.h"
#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
@@ -94,8 +96,9 @@
} // namespace
-constexpr char16_t kCapitalizedIbanPattern[] =
- u"^[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{7}[A-Z0-9]{0,18}$";
+constexpr char16_t kCapitalizedIbanGeneralPattern[] =
+ u"^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$";
+
// \u2006 - SIX-PER-EM SPACE (small space).
constexpr char16_t kEllipsisOneSpace = u'\u2006';
@@ -125,17 +128,17 @@
}
// static
-bool Iban::IsValid(const std::u16string& value) {
+bool Iban::IsValid(std::u16string_view value) {
std::u16string iban_value = RemoveIbanSeparators(value);
iban_value = base::i18n::ToUpper(iban_value);
- // IBANs must be at least 16 digits and at most 33 digits long.
- if (iban_value.length() < 16 || iban_value.length() > 33) {
+ // IBANs must be at least 15 digits and at most 33 digits long.
+ if (iban_value.length() < 15 || iban_value.length() > 33) {
return false;
}
// IBAN must match the regex pattern. Note that we made the IBAN uppercased,
// so we only need to check against an uppercased pattern.
- if (!MatchesRegex<kCapitalizedIbanPattern>(iban_value)) {
+ if (!MatchesRegex<kCapitalizedIbanGeneralPattern>(iban_value)) {
return false;
}
@@ -166,167 +169,57 @@
// static
Iban::IbanSupportedCountry Iban::GetIbanSupportedCountry(
std::string_view country_code) {
- if (country_code == "AD") {
- return IbanSupportedCountry::kAD;
- } else if (country_code == "AE") {
- return IbanSupportedCountry::kAE;
- } else if (country_code == "AL") {
- return IbanSupportedCountry::kAL;
- } else if (country_code == "AT") {
- return IbanSupportedCountry::kAT;
- } else if (country_code == "AZ") {
- return IbanSupportedCountry::kAZ;
- } else if (country_code == "BA") {
- return IbanSupportedCountry::kBA;
- } else if (country_code == "BE") {
- return IbanSupportedCountry::kBE;
- } else if (country_code == "BG") {
- return IbanSupportedCountry::kBG;
- } else if (country_code == "BH") {
- return IbanSupportedCountry::kBH;
- } else if (country_code == "BR") {
- return IbanSupportedCountry::kBR;
- } else if (country_code == "BY") {
- return IbanSupportedCountry::kBY;
- } else if (country_code == "CH") {
- return IbanSupportedCountry::kCH;
- } else if (country_code == "CR") {
- return IbanSupportedCountry::kCR;
- } else if (country_code == "CY") {
- return IbanSupportedCountry::kCY;
- } else if (country_code == "CZ") {
- return IbanSupportedCountry::kCZ;
- } else if (country_code == "DE") {
- return IbanSupportedCountry::kDE;
- } else if (country_code == "DK") {
- return IbanSupportedCountry::kDK;
- } else if (country_code == "DO") {
- return IbanSupportedCountry::kDO;
- } else if (country_code == "EE") {
- return IbanSupportedCountry::kEE;
- } else if (country_code == "EG") {
- return IbanSupportedCountry::kEG;
- } else if (country_code == "ES") {
- return IbanSupportedCountry::kES;
- } else if (country_code == "FI") {
- return IbanSupportedCountry::kFI;
- } else if (country_code == "FO") {
- return IbanSupportedCountry::kFO;
- } else if (country_code == "FR") {
- return IbanSupportedCountry::kFR;
- } else if (country_code == "GB") {
- return IbanSupportedCountry::kGB;
- } else if (country_code == "GE") {
- return IbanSupportedCountry::kGE;
- } else if (country_code == "GI") {
- return IbanSupportedCountry::kGI;
- } else if (country_code == "GL") {
- return IbanSupportedCountry::kGL;
- } else if (country_code == "GR") {
- return IbanSupportedCountry::kGR;
- } else if (country_code == "GT") {
- return IbanSupportedCountry::kGT;
- } else if (country_code == "HR") {
- return IbanSupportedCountry::kHR;
- } else if (country_code == "HU") {
- return IbanSupportedCountry::kHU;
- } else if (country_code == "IE") {
- return IbanSupportedCountry::kIE;
- } else if (country_code == "IL") {
- return IbanSupportedCountry::kIL;
- } else if (country_code == "IQ") {
- return IbanSupportedCountry::kIQ;
- } else if (country_code == "IS") {
- return IbanSupportedCountry::kIS;
- } else if (country_code == "IT") {
- return IbanSupportedCountry::kIT;
- } else if (country_code == "JO") {
- return IbanSupportedCountry::kJO;
- } else if (country_code == "KW") {
- return IbanSupportedCountry::kKW;
- } else if (country_code == "KZ") {
- return IbanSupportedCountry::kKZ;
- } else if (country_code == "LB") {
- return IbanSupportedCountry::kLB;
- } else if (country_code == "LC") {
- return IbanSupportedCountry::kLC;
- } else if (country_code == "LI") {
- return IbanSupportedCountry::kLI;
- } else if (country_code == "LT") {
- return IbanSupportedCountry::kLT;
- } else if (country_code == "LU") {
- return IbanSupportedCountry::kLU;
- } else if (country_code == "LV") {
- return IbanSupportedCountry::kLV;
- } else if (country_code == "LY") {
- return IbanSupportedCountry::kLY;
- } else if (country_code == "MC") {
- return IbanSupportedCountry::kMC;
- } else if (country_code == "MD") {
- return IbanSupportedCountry::kMD;
- } else if (country_code == "ME") {
- return IbanSupportedCountry::kME;
- } else if (country_code == "MK") {
- return IbanSupportedCountry::kMK;
- } else if (country_code == "MR") {
- return IbanSupportedCountry::kMR;
- } else if (country_code == "MT") {
- return IbanSupportedCountry::kMT;
- } else if (country_code == "MU") {
- return IbanSupportedCountry::kMU;
- } else if (country_code == "NL") {
- return IbanSupportedCountry::kNL;
- } else if (country_code == "PK") {
- return IbanSupportedCountry::kPK;
- } else if (country_code == "PL") {
- return IbanSupportedCountry::kPL;
- } else if (country_code == "PS") {
- return IbanSupportedCountry::kPS;
- } else if (country_code == "PT") {
- return IbanSupportedCountry::kPT;
- } else if (country_code == "QA") {
- return IbanSupportedCountry::kQA;
- } else if (country_code == "RO") {
- return IbanSupportedCountry::kRO;
- } else if (country_code == "RS") {
- return IbanSupportedCountry::kRS;
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/components/autofill/core/browser/data_model/payments/iban_unittest.cc b/components/autofill/core/browser/data_model/payments/iban_unittest.cc
index 9715e1e3..c42944f 100644
--- a/components/autofill/core/browser/data_model/payments/iban_unittest.cc
+++ b/components/autofill/core/browser/data_model/payments/iban_unittest.cc
@@ -338,6 +338,19 @@
// KW16 will be converted into 203216, and the remainder on 97 is 1.
EXPECT_FALSE(Iban::IsValid(u"KW1600000000000000000"));
+ // Valid IBANs for several other countries.
+ EXPECT_TRUE(Iban::IsValid(u"KZ58125KZT1234567890"));
+ EXPECT_TRUE(Iban::IsValid(u"RO49AAAA1B31007593840000"));
+ EXPECT_TRUE(Iban::IsValid(u"LC09HEMM000000000000000123456789"));
+ EXPECT_TRUE(Iban::IsValid(u"MT84MALT011000012345MTLCAST001S"));
+ EXPECT_TRUE(Iban::IsValid(u"SC18SSCB11010000000000001497USD"));
+ EXPECT_TRUE(Iban::IsValid(u"MD24AG000225100013104168"));
+ EXPECT_TRUE(Iban::IsValid(u"BH67BMAG00001299123456"));
+ EXPECT_TRUE(Iban::IsValid(u"LI21088100002324013AA"));
+ EXPECT_TRUE(Iban::IsValid(u"FR1420041010050500013M02606"));
+ EXPECT_TRUE(Iban::IsValid(u"LB62099900000001001901229114"));
+ EXPECT_TRUE(Iban::IsValid(u"NO9386011117947"));
+
// The IBAN value country code is invalid.
EXPECT_FALSE(Iban::IsValid(u"XXA1CBKU0000000000001234560101"));
}
diff --git a/components/autofill/core/browser/data_quality/validation_unittest.cc b/components/autofill/core/browser/data_quality/validation_unittest.cc
index 578decb3..73a6c62a2 100644
--- a/components/autofill/core/browser/data_quality/validation_unittest.cc
+++ b/components/autofill/core/browser/data_quality/validation_unittest.cc
@@ -257,30 +257,6 @@
EXPECT_TRUE(IsUPIVirtualPaymentAddress(u"1234123412341234@rupay.npci"));
}
-class AutofillIsInternationalBankAccountNumber
- : public testing::TestWithParam<std::u16string> {};
-
-INSTANTIATE_TEST_SUITE_P(InternationalBankAccountNumber,
- AutofillIsInternationalBankAccountNumber,
- testing::Values(u"MT84MALT011000012345MTLCAST001S",
- u"SC18SSCB11010000000000001497USD",
- u"MD24AG000225100013104168",
- u"BH67BMAG00001299123456",
- u"LI21088100002324013AA",
- u"NO9386011117947",
- u"FR1420041010050500013M02606",
- u"LB62099900000001001901229114"));
-
-TEST_P(AutofillIsInternationalBankAccountNumber,
- IsInternationalBankAccountNumber) {
- EXPECT_TRUE(IsInternationalBankAccountNumber(GetParam())) << GetParam();
- EXPECT_TRUE(IsInternationalBankAccountNumber(u" " + GetParam() + u" "));
- EXPECT_FALSE(IsInternationalBankAccountNumber(u"DE" + GetParam()));
- EXPECT_FALSE(IsInternationalBankAccountNumber(GetParam() + u"."));
- EXPECT_FALSE(IsInternationalBankAccountNumber(
- GetParam() + u"0000000000000000000000000000000000000"));
-}
-
TEST(AutofillValidation, IsValidAchRoutingTransitNumber) {
// Must be 9 digits, cannot have text:
EXPECT_FALSE(IsAchRoutingTransitNumber(u"12345678"));
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