6

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...).
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • Fun fact: looks like changing label names to english stops the autocomplete: https://jsfiddle.net/8gLxpwsj/ – Ava_Katushka Sep 29 '20 at 11:20
  • @Ava_Katushka: Yep, we also noticed that. It only happens when the UI language is German. – Heinzi Sep 29 '20 at 11:21
  • 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... – JHH Dec 01 '21 at 10:35

2 Answers2

5

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:

Heinzi
  • 167,459
  • 57
  • 363
  • 519
1

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

Ava_Katushka
  • 144
  • 8