Why does Chrome think that my form is a credit card form?
Asked Answered
J

2

8

Minimal repro example (jsfiddle, you need a credit card saved in your browser to see this issue):

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>
    <form method="post" action="Test.html" autocomplete="off">
        <div>
            <label>Basisnummer</label>
            <input type="text" />
            <input type="text" />
            <br>

            <label>Markenname</label>
            <input type="text" />
        </div>
    </form>
</body>
</html>

Both Chrome 85.0.4183.121 and Edge 85.0.564.63 think that this is a credit card form and decide to helpfully allow my users to enter their credit card data, which is not at all helpful (since this is not a credit card form) and confuses the heck out of my users:

screen shot


I am aware of the following workarounds:

  • Obfuscating the first label:

    <label>Basisnum<span style="display:none">x</span>mer</label>
    

    That works, but I'd be a lot of work to implement this in our application (the labels are not hard-coded since they can be localized).

  • autocomplete="cc-csc" works (i.e., disables auto-completion), but it's semantically completely wrong (it's not a CC-CSC field!), so I'd rather avoid that to prevent further trouble down the road when browsers decide to do something "helpful" to cc-csc fields. For example, setting it as cc-csc could make mobile browsers show a numeric-only keyboard (makes sense, since a csc is always numeric), and I definitely don't want that.


In any case, I'd rather work with the browser than against it, hence my question:

Why does this happen? (Since it occurs in both Chrome and "new" Edge, it must be some Chromium issue, and since Chromium is open-source, we should be able to see what happens here, right?)

Bonus question: How can I (officially) tell Chromium that this is not a credit card form?


Notes:

  • autocomplete="nope" (or autocomplete="...some random data...") doesn't make a difference.
  • This is just a minimal example - the full page has names, classes, ids and whatnot.
  • I am grateful for people suggesting workarounds in the comments. I would, however, prefer to understand why it happens rather than trying random workarounds (if that is possible, of course...).
Josephson answered 29/9, 2020 at 11:3 Comment(4)
Fun fact: looks like changing label names to english stops the autocomplete: jsfiddle.net/8gLxpwsjJornada
@Ava_Katushka: Yep, we also noticed that. It only happens when the UI language is German.Josephson
This happens for me with an app having a single input field called fullName. Locale is en-US. There's nothing remotely similar to a number or a cc- field anywhere in the application, but every time the user is prompted to enter their full name, Chrome suggests to enter their credit card number instead...Briannabrianne
I have created this issue: issues.chromium.org/issues/339033226 Support it and let's ask for a permanent solution for this!Boondocks
J
6

It's because Chome's auto-detection of German-language credit card forms is too aggressive. In particular, your form contains

  • three or more fields,
  • one of which is labeled as a ...nummer, and
  • another one is labeled as a ...name.

Here is an even simpler minimal example that reproduces the same issue with the current canary version of Chrome (87.0.4278.0):

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>
    <div>
        <label>Nummer</label>
        <input type="text" />
        <input type="text" />
        <br>

        <label>Name</label>
        <input type="text" />
    </div>
</body>
</html>

Looking at the source of Chromium, we can see that the following regex is used to detect credit card number fields (components/autofill/core/common/autofill_regex_constants.cc):

const char kCardNumberRe[] =
    "(add)?(?:card|cc|acct).?(?:number|#|no|num|field)"
    "|(?<!telefon|haus|person|fødsels)nummer"  // de-DE, sv-SE, no
    "|カード番号"                              // ja-JP
    "|Номер.*карты"                            // ru
    "|信用卡号|信用卡号码"                     // zh-CN
    "|信用卡卡號"                              // zh-TW
    "|카드"                                    // ko-KR
    // es/pt/fr
    "|(numero|número|numéro)(?!.*(document|fono|phone|réservation))";

We can see that (almost) every field labeled with "...nummer" (= German for "number") is considered a credit card number field!

Once a credit card number field is found, a subsequent field labeled "...name" is treated as a credit card name field (credit_card_field.cc):

// Sometimes the cardholder field is just labeled "name". Unfortunately
// this is a dangerously generic word to search for, since it will often
// match a name (not cardholder name) field before or after credit card
// fields. So we search for "name" only when we've already parsed at
// least one other credit card field and haven't yet parsed the
// expiration date (which usually appears at the end).
if (fields > 0 && !credit_card_field->expiration_month_ &&
    ParseField(scanner, base::UTF8ToUTF16(kNameOnCardContextualRe),
               &credit_card_field->cardholder_,
               {log_manager, "kNameOnCardContextualRe"})) {
  continue;

Unfortunately, there is no "official" way to tell Chrome that "this is really not a credit card field". The most common workaround is autocomplete="cc-csc", but this is semantically completely backwards (mis-labeling a field as a certain type of credit card field to prevent credit card field auto-detection).

I have submitted a bug report for this, let's hope it helps:

Josephson answered 30/9, 2020 at 18:12 Comment(0)
J
2

You can explicitly set autocomplete values to the closest approximations from the The HTML autocomplete attribute

I used "tel" for Basisnummer and "organization" for Markenname:

<form method="post" action="Test.html" autocomplete="off">
    <div>
        <label>Basisnummer</label>
        <input type="text" autocomplete="tel"/>
        <input type="text" />
        <br>

        <label>Markenname</label>
        <input type="text" autocomplete="organization"/>
    </div>
</form>

It does disable card number autocomplete. JSfiddle

Jornada answered 29/9, 2020 at 11:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.