Ciemny wzór autouzupełniania
Opublikowany: 2022-03-10Formularz rejestracyjny gazety zawierał pola na imię i nazwisko, adres e-mail i hasło. Zacząłem więc pisać w polu nazwy, a autouzupełnianie zasugerowało mój profil. Ale było coś fajnego . Sugestia autouzupełniania zawierała mój adres pocztowy. Nie trzeba dodawać, że było to zastanawiające: adres nie był polem w formularzu. Dlaczego w ogóle to zasugerowano?
Zanim to pytanie zaczęło formować się w moim umyśle, mój mózg już zasygnalizował mojemu palecowi, aby kliknął sugestię i zostało to zrobione. Następnie zostałem przeniesiony na drugą stronę formularza, która zażądała dodatkowych informacji, takich jak adres, telefon, data urodzenia i tak dalej. Wszystkie te pola zostały również wstępnie wypełnione przez funkcję autouzupełniania.
Westchnąłem z ulgą. To była „wielostopniowa” forma, a nie sztuczka ze strony internetowej. W końcu była to renomowana gazeta. Usunąłem wszystkie opcjonalne informacje z drugiej strony, zakończyłem rejestrację i ruszyłem dalej.
Ta (trudna) interakcja podkreśliła jedno z zagrożeń związanych z używaniem funkcji autouzupełniania .
Autouzupełnianie i autouzupełnianie
Mogą brzmieć podobnie, ale autocomplete
i autouzupełnianie to nie to samo . Chociaż są blisko spokrewnione:
- Autouzupełnianie to funkcja przeglądarki, która pozwala ludziom zapisywać informacje (w przeglądarce lub systemie operacyjnym) i używać ich w formularzach internetowych.
-
autocomplete
to atrybut HTML, który zapewnia przeglądarce wskazówki dotyczące (lub nie) automatycznego wypełniania pól w formularzu internetowym.
Można powiedzieć, że autouzupełnianie to „co”, podczas gdy autouzupełnianie to „jak”, tj. autofill
przechowuje dane i próbuje je dopasować w formularzu internetowym (na podstawie name
pola, type
lub id
), a autocomplete
prowadzi przeglądarkę jak to zrobić (jakie informacje są oczekiwane w każdym polu).
Autouzupełnianie to potężna funkcja z wieloma opcjami, która pozwala określić wiele różnych typów wartości:
- Dane osobowe : imię i nazwisko, adres, telefon, data urodzenia;
- Dane finansowe : numer karty kredytowej, imię i nazwisko, data ważności;
- Dane demograficzne : lokalizacja, wiek, płeć, język;
- Zawód : firma i tytuł zawodowy.
Autouzupełnianie jest szeroko rozpowszechnioną funkcją z wyboru lub przez przypadek: kto nie zgodził się na zapisywanie/używanie przez przeglądarkę informacji z formularza internetowego, celowo lub przez pomyłkę? I to może stanowić problem — zwłaszcza w połączeniu ze złym wykorzystaniem autocomplete
(i dodatkową oburzającą liczbą e-maili phishingowych i SMS-ów w dzisiejszych czasach).
Zagrożenia prywatności
Obie te cechy niosą ze sobą (co najmniej) dwa główne zagrożenia dla użytkownika, oba związane z jego danymi osobowymi i prywatnością:
- Pola niewidoczne są wypełniane (to nie to samo, co pola z ukrytym typem);
- Informacje autouzupełniane można odczytać za pomocą JavaScript jeszcze przed przesłaniem formularza przez użytkownika.
Oznacza to, że gdy użytkownik wybierze autouzupełnianie informacji, programista będzie mógł przeczytać wszystkie pola . Ponownie, niezależnie od tego, czy użytkownik przesyła formularz, czy nie, użytkownik nie wie, jakie pola zostały faktycznie wypełnione.
Ta ostatnia część jest względna: wiedza o tym, jakie pola są wypełnione, będzie zależeć od przeglądarki. Safari i Firefox wykonują w tym dobrą robotę (co wkrótce zobaczymy poniżej). Z drugiej strony Chrome, obecnie najpopularniejsza przeglądarka, oferuje złe doświadczenia, które mogą skłonić nawet najbardziej doświadczonych użytkowników do udostępnienia swoich danych osobowych.
Jeśli weźmiemy również pod uwagę czasy, w których użytkownik przypadkowo decyduje się wypełnić pola, kwestia ta staje się bardziej istotna. Sprawdźmy to bardziej szczegółowo na przykładzie.
Mały eksperyment
Przeprowadziłem mały eksperyment tworząc formularz z wieloma polami i dołączając atrybut autocomplete
z różnymi wartościami. Potem pobawiłem się trochę strukturą formularza:
- Ukryłem większość pól, umieszczając je w kontenerze poza ekranem (zamiast używać
hidden
lubtype="hidden"
); - Usunąłem wizualnie ukryte pola z kolejności tabulacji (aby użytkownicy klawiatury przeoczyli ukryte pola);
- Próbowałem posortować pola w innej kolejności (i ku mojemu zdziwieniu wpłynęło to na autouzupełnianie!).
Ostatecznie kod formularza wyglądał tak:
<form method="post" action="javascript:alertData()"> <label for="name">Full name</label><input name="name" autocomplete="name" /><br/> <label for="email">Email</label><input name="email"/><br/> <label for="postal-code">ZIP</label><input name="postal-code" autocomplete="postal-code"/> <div class="hide-this"> <!-- Hidden --> <label for="firstname">First name</label><input tabindex="-1" type="hidden" name="firstname" autocomplete="given-name" /><br/> <label for="lastname">Last name</label><input tabindex="-1" name="lastname" autocomplete="family-name" /><br/> <label for="honorific-prefix">honorific-prefix</label><input tabindex="-1" name="honorific-prefix" autocomplete="honorific-prefix"/><br/> <label for="organization">Organization</label><input tabindex="-1" name="organization" /><br/> <label for="phone">Phone</label><input tabindex="-1" name="phone" autocomplete="tel" /><br/> <label for="address">address</label><input tabindex="-1" name="address" autocomplete="street-address" /><br/> <label for="city">City</label><input tabindex="-1" name="city" autocomplete="address-level2" /><br/> <label for="state">State</label><input tabindex="-1" name="state" autocomplete="address-level1" /><br/> <label for="level3">Level3</label><input tabindex="-1" name="state" autocomplete="address-level3" /><br/> <label for="level4">Level4</label><input tabindex="-1" name="state" autocomplete="address-level4" /><br/> <label for="country">Country</label><input tabindex="-1" name="country" autocomplete="country" /><br/> <label for="birthday">Birthday</label><input tabindex="-1" name="birthday" autocomplete="bday" /><br/> <label for="language">Language</label><input tabindex="-1" name="language" autocomplete="language" /><br/> <label for="sex">Sex</label><input tabindex="-1" name="sex" autocomplete="sex" /><br/> <label for="url">URL</label><input tabindex="-1" name="url" autocomplete="url" /><br/> <label for="photo">Photo</label><input tabindex="-1" name="photo" autocomplete="photo" /><br/> <label for="impp">IMPP</label><input tabindex="-1" name="impp" autocomplete="impp" /><br/> <label for="username">Username</label><input tabindex="-1" name="username" autocomplete="username" /><br/> <label for="password">Password</label><input tabindex="-1" name="password" autocomplete="password" /><br/> <label for="new-password">Password New</label><input tabindex="-1" name="new-password" autocomplete="new-password" /><br/> <label for="current-password">Password Current</label><input tabindex="-1" name="current-password" autocomplete="current-password" /><br/> <label for="cc">CC#</label><input tabindex="-1" name="cc" autocomplete="cc-number" /><br/> <label for="cc-name">CC Name</label><input tabindex="-1" name="cc-name" autocomplete="cc-name" /><br/> <label for="cc-expiration">CC expiration</label><input tabindex="-1" name="cc-expiration" autocomplete="cc-expiration" /><br/> <label for="cc-zipcode">CC Zipcode</label><input tabindex="-1" name="cc-zipcode" autocomplete="cc-postalcode" /><br/> </div> <button>Submit</button> </form>
Uwaga: stworzyłem to demo jakiś czas temu, a standardem jest żywy dokument. Od tego czasu niektóre nazwy autouzupełniania uległy zmianie. Na przykład teraz możemy określić new-password
i current-password
lub więcej szczegółów dotyczących adresu lub karty kredytowej, które nie były wcześniej dostępne.
Formularz ten miał trzy widoczne pola ( name
, e- email
i zipcode
). Chociaż ten formularz jest powszechny wśród firm ubezpieczeniowych, telewizji kablowej i innych dostawców usług, może nie być zbyt rozpowszechniony, więc zmniejszyłem go jeszcze bardziej za pomocą jednego pola e-mail. Widzimy to wszędzie, aby zarejestrować się w witrynach internetowych, biuletynach lub aktualizacjach. Tutaj możesz zobaczyć działające demo:
Jeśli użyłeś autouzupełniania do wypełnienia formularza, już udostępniłeś więcej informacji niż chciałeś ( nie martw się, wszystkie są lokalne i nie zostały udostępnione mi ). A w Chrome może nawet wyglądać jak zupełnie normalny formularz subskrypcji.
Jeśli nie masz/nie używasz autouzupełniania, nie martw się. Oto podsumowanie tego, jak działa w trzech różnych przeglądarkach.
Uwaga : wszystkie te testy zakładają użycie funkcji autouzupełniania i opierają się na fałszywym profilu!
Safari
Po kliknięciu kontrolki formularza Safari wyświetli ikonę po prawej stronie pola. Kliknięcie w nią spowoduje wyświetlenie wyskakującego okienka z informacją, którą przeglądarka udostępni wraz z formularzem:
Dobra rzecz: wyświetla wszystkie dane, które będą udostępniane w ramach formularza. Nie tylko dane dla widocznych pól, ale wszystkie. W tym momencie użytkownik może podejrzewać, że coś jest nie w porządku. Jest coś podejrzanego.
Kiedy zredukowałem formularz tylko do pola e-mail, Safari zrobiło coś interesującego. Wyskakujące okienko autouzupełniania było inne:
Stwierdza, że udostępni tylko wiadomość e-mail (i udostępnia tylko tę informację). Ale poniższe informacje kontaktowe mogą być trudniejsze. Po kliknięciu tego przycisku przeglądarka wyświetla podsumowanie profilu z udostępnionymi danymi. Ale nie jest to nigdzie jasno określone. Po prostu wygląda jak zwykła wizytówka z kilkoma opcjami „udostępniaj/nie udostępniaj”. Po kliknięciu przycisku „Autouzupełnianie” formularz zostanie wypełniony wszystkimi danymi. Nie tylko e-mail:
Istnieje więc sposób, aby użytkownik nieumyślnie udostępnił informacje w formularzu. Jest to trudne, ale niezbyt naciągane, biorąc pod uwagę, że jest to ta „podświetlona” ikoną z dwóch możliwych opcji.
Zabawne, przeglądarki oddzielają dane osobowe od danych karty kredytowej, ale Safari wypełniła część informacji o karcie kredytowej na podstawie danych osobowych (imię i nazwisko oraz kod pocztowy).
Firefox
Korzystanie z autouzupełniania w Firefoksie jest nieco bardziej złożone. Nie jest to automatyczne jak w Chrome i nie ma ikony jak w Safari. Użytkownicy będą musieli zacząć pisać lub kliknąć po raz drugi, aby zobaczyć wyskakujące okienko autouzupełniania, które będzie zawierało notatkę z każdą kategorią, którą wypełni przeglądarka, a nie tylko z widocznymi polami:
Testując z formularzem tylko e-mail, Firefox zaprezentował to samo wyskakujące okienko autouzupełniania, informujące, które kategorie pól zostanie wypełnione. Żadna różnica.
I podobnie jak w innych przeglądarkach, po uruchomieniu autouzupełniania mogliśmy odczytać wszystkie wartości za pomocą JavaScript.
Firefox był najlepszy z tej trójki: jasno określał, jakie informacje będą udostępniane formularzowi niezależnie od pól czy ich kolejności. I ukrył funkcję autouzupełniania po drugiej interakcji użytkownika.
Użytkownik klawiatury może wybrać autouzupełnianie, nie zdając sobie z tego sprawy, wchodząc do wyskakującego okienka i naciskając klawisz tabulatora.
Chrom
Potem przyszła kolej na Chrome. (Tutaj używam „Chrome”, ale wyniki były podobne dla kilku przetestowanych przeglądarek opartych na Chromium.) Kliknąłem pole i bez dalszej interakcji pokazało się wyskakujące okienko autouzupełniania. Chociaż Firefox i Safari miały wiele wspólnego, Chrome jest zupełnie inny: pokazuje tylko dwie wartości i obie są widoczne.
Ten wyświetlacz był zgodny z projektem. Celowo wybrałem kolejność pól, aby uzyskać tę konkretną kombinację widocznych kontrolek i sugestii autouzupełniania. Wygląda jednak na to, że Chrome daje niektórym właściwościom autouzupełniania większą „wagę” dla drugiej wartości. A to sprawia, że wyskakujące okienko zmienia się w zależności od kolejności pól w formularzu.
Testowanie z drugą wersją formularza nie było dużo lepsze:
Podczas gdy wyskakujące okienko pokazuje pole, które nie jest widoczne (nazwę), nie jest jasne, jaki jest cel nazwy w wyskakującym okienku. Doświadczony użytkownik może wiedzieć, że dzieje się tak, ponieważ nazwa jest udostępniana, ale przeciętny użytkownik (a nawet doświadczeni) może myśleć, że e-mail jest powiązany z profilem o tej nazwie. Brak wskazania danych, które przeglądarka będzie udostępniać formularzowi.
A gdy tylko użytkownik kliknie przycisk autouzupełniania, dane są dostępne dla programisty do odczytania za pomocą JavaScript:
Chrome był najgorszym przestępcą: automatycznie udostępniał informacje, nie było jasne, jakie dane są w to zaangażowane, a sugestie autouzupełniania zmieniały się w zależności od kolejności i atrybutów elementów sterujących.
Pierwsze dwa problemy są wspólne dla wszystkich/wielu przeglądarek do tego stopnia, że można je nawet uznać za funkcję. Jednak trzeci problem dotyczy wyłącznie przeglądarek Chromium i ułatwia szkicowy ciemny wzór.
Takie zachowanie byłoby bardziej anegdotą i nie stanowiłoby problemu, gdyby nie to, ponieważ Chrome ma znaczny udział w rynku przeglądarek online (w tym Chrome i oparte na Chromium).
Ciemny wzór
Jak zapewne wiesz, ciemny wzór to zwodniczy wzór UX, który nakłania użytkowników do robienia rzeczy, których tak naprawdę nie chcą robić.
„Kiedy korzystasz ze stron internetowych i aplikacji, nie czytasz każdego słowa na każdej stronie — czytasz przeglądowo i przyjmujesz założenia. Jeśli firma chce cię nakłonić do zrobienia czegoś, może to wykorzystać, sprawiając, że strona wygląda tak, jakby mówiła jedną rzecz, podczas gdy w rzeczywistości mówi coś innego”.
— Harry Brignull, darkpatterns.org
Zachowanie opisane w poprzednich punktach jest wyraźnie zwodniczym doświadczeniem użytkownika. Niedoświadczeni użytkownicy nie zdadzą sobie sprawy, że udostępniają swoje dane osobowe . Nawet bardziej zaawansowani technicznie ludzie mogą zostać przez to oszukani, ponieważ Chrome sprawia, że wygląda na to, że wybrana opcja należy do profilu, zamiast jasno określać, jakie informacje są udostępniane.
Implementacje przeglądarki powodują to zachowanie, ale wymaga to od programisty ustawienia go w celu wykorzystania go. Niestety, są już firmy, które chcą go wykorzystać, sprzedając go jako funkcję do pozyskiwania leadów.
Dopóki pojawia się ciemny wzór, może to być również nielegalny. Łamie bowiem wiele zasad dotyczących przetwarzania danych osobowych określonych w art. 5 europejskiego ogólnego rozporządzenia o ochronie danych (RODO):
- Zgodność z prawem, uczciwość i przejrzystość
Proces jest prawie przejrzysty. - Ograniczenie celu
Dane przetwarzane są w sposób niezgodny z pierwotnym celem. - Minimalizacja danych
Wręcz przeciwnie. Maksymalizacja danych: uzyskaj jak najwięcej informacji.
Na przykład, jeśli chcesz zapisać się do newslettera lub poprosić o informacje o produkcie i podasz swój adres e-mail, witryna nie ma prawa do uzyskania Twojego imienia i nazwiska, adresu, daty urodzenia, numeru telefonu ani czegokolwiek innego bez Twojego zgoda lub wiedza. Nawet jeśli uznałeś, że użytkownik wyraził zgodę po kliknięciu w autouzupełnianie, cel pozyskanych danych nie jest zgodny z pierwotną intencją formularza.
Możliwe rozwiązania
Aby uniknąć problemu, wszyscy aktorzy muszą wnieść swój wkład i pomóc rozwiązać problem:
- Użytkownicy
- Deweloperzy i projektanci
- Przeglądarki
1. Użytkownicy
Jedyną rzeczą po stronie użytkownika jest upewnienie się, że dane wyświetlane w wyskakującym okienku autouzupełniania są poprawne .
Ale musimy pamiętać, że ofiarą jest tutaj użytkownik. Moglibyśmy ich winić za to, że nie zwracali wystarczającej uwagi podczas klikania autouzupełniania, ale byłoby to niesprawiedliwe. Ponadto istnieje wiele powodów, dla których dana osoba może omyłkowo kliknąć przycisk i przypadkowo udostępnić swoje dane. Więc nawet użytkownicy mający dobre intencje i doświadczeni mogą się na to nabrać.
2. Deweloperzy i projektanci
Bądźmy szczerzy. Chociaż programiści nie są główną przyczyną problemu, odgrywają kluczową rolę w wykorzystywaniu ciemnego wzorca. Przypadkowo lub w złych zamiarach.
I bądźmy odpowiedzialni i uczciwi (tym razem w sposób dosłowny), ponieważ to jest rzecz, którą programiści i projektanci mogą zrobić, aby zbudować zaufanie i dobrze wykorzystać funkcje autouzupełniania i autouzupełniania:
- Automatycznie uzupełniaj tylko te dane, których potrzebujesz.
- Wyraźnie określ, jakie dane będą gromadzone.
- Nie ukrywaj pól formularza, które zostaną później przesłane.
- Nie wprowadzaj w błąd ani nie nakłaniaj użytkowników do wysyłania większej ilości danych.
Jako środek ekstremalny spróbuj unikać autouzupełniania niektórych pól. Ale oczywiście wiąże się to z innymi problemami, ponieważ sprawi, że formularz będzie mniej użyteczny i dostępny. Więc znalezienie równowagi może być trudne.
Wszystko to bez uwzględnienia możliwości wystąpienia luki XSS, która mogłaby wykorzystać ciemny wzorzec. Oczywiście byłaby to zupełnie inna historia i jeszcze ważniejszy problem.
3. Przeglądarki
Duża część pracy musiałaby zostać wykonana od strony przeglądarki (zwłaszcza po stronie Chromium). Ale zacznę od stwierdzenia, że nie wszystko jest złe z tym, jak przeglądarki internetowe obsługują autouzupełnianie/autouzupełnianie. Wiele rzeczy jest dobrych. Na przykład:
- Ograniczają dane, które mogą być udostępniane
Przeglądarki mają listę pól do autouzupełniania, która może nie zawierać wszystkich wartości opisanych w standardzie HTML. - Hermetyzują i grupują dane
Przeglądarki oddzielają informacje osobiste i finansowe, aby chronić krytyczne wartości, takie jak karty kredytowe. Safari miał z tym pewne problemy, ale były one niewielkie. - Ostrzegają przed udostępnieniem danych
Czasami może to być niekompletne (Chrome) lub niejasne (Safari), ale ostrzegają użytkownika.
Mimo to niektóre rzeczy można poprawić za pomocą wielu lub wszystkich przeglądarek internetowych.
Pokaż wszystkie pola, które będą uzupełniane automatycznie
Przeglądarki powinny zawsze pokazywać listę wszystkich pól, które będą automatycznie uzupełniane w wyskakującym okienku autouzupełniania (zamiast tylko częściowej listy). Ponadto informacje powinny być wyraźnie oznaczone jako dane do udostępnienia, a nie wyświetlane jako zwykła wizytówka, która może wprowadzać w błąd.
Firefox spisał się w tym momencie znakomicie, Safari ogólnie wykonało dobrą robotę, a Chrome był kiepski w porównaniu z pozostałymi dwoma.
Nie uruchamiaj zdarzenia onChange
autouzupełniania
Byłoby to problematyczne żądanie, ponieważ to zachowanie jest częścią definicji autouzupełniania w standardzie HTML:
„Mechanizm autouzupełniania musi być zaimplementowany przez agenta użytkownika działający tak, jakby użytkownik zmodyfikował dane kontrolki […].”
Oznacza to, że przeglądarki powinny traktować autouzupełniane dane tak, jakby zostały wprowadzone przez użytkownika, wywołując w ten sposób wszystkie zdarzenia, pokazując wartości itp. Nawet na polu niedostępnym wizualnie.
Zapobieganie takiemu zachowaniu na niewidocznych elementach może rozwiązać problem. Ale sprawdzanie, czy kontrolka formularza jest widoczna, czy nie, może być kosztowne dla przeglądarki. Ponadto to rozwiązanie jest tylko częściowe, ponieważ programiści mogą nadal odczytywać wartości nawet bez danych wejściowych wyzwalających zdarzenia.
Nie zezwalaj programistom na odczytywanie pól z autouzupełnianiem przed przesłaniem
Byłoby to również problematyczne, ponieważ wielu programistów często polega na odczytywaniu wartości pól przed ich przesłaniem, aby sprawdzić poprawność wartości (np. gdy użytkownik odchodzi od danych wejściowych). Ale miałoby to sens: użytkownik nie chce udostępniać informacji dopóki nie prześlą formularza, więc przeglądarka też nie powinna.
Alternatywą byłoby dostarczanie fałszywych danych podczas odczytywania wartości autouzupełnianych. Przeglądarki internetowe robią już coś takiego z odwiedzanymi linkami, dlaczego nie zrobić tego samego z automatycznie uzupełnianymi polami formularzy? Podać bezużyteczną nazwę jako nazwę, prawidłowy adres zgodny z lokalnymi władzami zamiast adresu użytkownika, fałszywy numer telefonu? Może to rozwiązać potrzeby weryfikacji deweloperów, jednocześnie chroniąc dane osobowe użytkownika.
Wyświetlenie pełnej listy pól/wartości, które przeglądarka będzie wyraźnie udostępniać w formularzu, byłoby świetnym krokiem naprzód. Pozostałe dwa są idealne, ale bardziej stretch goale. Mimo to są to inicjatywy, które znacznie poprawiłyby prywatność.
Czy ciemny wzór autouzupełniania nadal będzie możliwy do wykorzystania? Niestety tak. Ale byłoby to o wiele bardziej skomplikowane. I w tym momencie to na użytkowniku i obowiązkiem dewelopera byłoby uniknięcie takiej sytuacji.
Wniosek
Możemy argumentować, że autouzupełnianie nie jest dużym problemem bezpieczeństwa (nawet w Chrome), ponieważ wymaga interakcji użytkownika w celu wybrania informacji. Możemy jednak również argumentować, że potencjalna utrata danych uzasadnia właściwe działanie. A Chrome wprowadził więcej zmian dotyczących (stosunkowo) mniej ważnych problemów związanych z bezpieczeństwem/użytecznością (zobacz alert()
, prompt()
i confirm()
niż to, co można zrobić, aby chronić kluczowe dane osobowe.
Następnie pojawia się kwestia ciemnego wzoru. Można tego uniknąć, jeśli wszyscy wykonają swoją część:
- Użytkownicy powinni uważać na formularze/dane, które wypełniają automatycznie;
- Deweloperzy powinni unikać wykorzystywania tych danych;
- Przeglądarki powinny lepiej chronić dane ludzi.
U podstaw tego ciemnego wzoru jest problem z przeglądarką (i głównie z Chrome), a nie mały (prywatność powinna być kluczowa w Internecie). Ale jest wybór. Ostatecznie wykorzystanie ciemnego wzoru zależy od twórców. Wybierzmy więc mądrze i zróbmy właściwą rzecz.
Dalsza lektura na Smashing Magazine
- Lepszy projekt formy: jedna rzecz na stronę (studium przypadku), Adam Silver
- Wspólne obawy i prywatność w formularzach internetowych, Witalij Friedman
- Uproszczenie stylów form z
accent-color
, Michelle Barker - Typy danych wejściowych HTML5: gdzie są teraz?, Drew McLellan
- Formularze i walidacja w reakcji jonowej, Jerry Navi
- Najlepsze praktyki projektowania formularzy mobilnych, Nick Babich