zabezpieczanie przeglądów internetowych za pomocą niestandardowych kart Chrome

Plaid wzmacnia innowatorów w obszarze fintech, zapewniając im dostęp do danych finansowych za pośrednictwem jednolitego interfejsu API. Aby pomóc użytkownikom końcowym połączyć dane bankowe z aplikacjami fintech, Plaid opracował Link, moduł drop-in, który obsługuje walidację poświadczeń, uwierzytelnianie wieloskładnikowe i obsługę błędów dla każdego obsługiwanego banku.

Programiści Androida wcześniej musieli otwierać adresy URL linków w przeglądarkach internetowych. Każda aplikacja, która chciała użyć linka, wymagała dużego wysiłku programisty, a bez standaryzacji niektóre implementacje musiały zawierać błędy. Aby poprawić wrażenia programistów, niedawno opublikowaliśmy zestaw SDK, dzięki któremu Widok sieci Web można łatwo zintegrować z dowolną aplikacją za pomocą kilku linii kodu.

ponadto przeglądanie stron internetowych nie jest całkowicie bezpieczne dla użytkowników końcowych, którzy wprowadzają poufne informacje do przepływu łączy. Aby nasz zestaw SDK był jak najbardziej bezpieczny, zaimplementowaliśmy go za pomocą niestandardowych kart Chrome zamiast Android WebViews. W tym artykule wyjaśniamy, dlaczego podjęliśmy tę decyzję i jak przezwyciężyliśmy problemy techniczne, które napotkaliśmy po drodze.

oceniając nasze opcje

jako SDK, nasz kod działa w aplikacjach innych programistów, a co za tym idzie, w ich procesach aplikacyjnych. Aby uruchomić aplikację internetową Link w widoku sieci Web, Javascript musi być włączony. Otwiera to drzwi dla innych aplikacji do uruchamiania złośliwego kodu, takiego jak rejestrowanie wywołań zwrotnych, które próbują przechwycić nazwy użytkowników i hasła. Ponadto złośliwa aplikacja może otworzyć inną stronę internetową, która naśladuje przepływ łącza podczas próby phishingu.

szukając rozwiązania łatwego do integracji dla programistów, intuicyjnego dla użytkowników końcowych i bezpiecznego, oceniliśmy kilka opcji:

  1. budowanie natywnego przepływu łącza: ponieważ natywne przepływy łącza uruchamiałyby się również w procesie innej aplikacji, doświadczeni programiści mogliby użyć reflection, aby znaleźć nasze edycje wejściowe i zarejestrować wywołania zwrotne w sposób podobny do Javascript w widoku sieci Web.

  2. tworzenie oddzielnej aplikacji authenticator: Zapewniłoby to natywne doświadczenie w piaskownicy i byłoby idealnym doświadczeniem dla użytkowników końcowych; jednak wielu użytkowników nie chciałoby pobierać dodatkowej aplikacji ze Sklepu Play. Oznacza to, że potrzebujemy rozwiązania awaryjnego dla użytkowników, którzy odmawiają pobrania aplikacji.

  3. otwieranie linku w osobnym oknie przeglądarki: byłoby to bezpieczne rozwiązanie w piaskownicy. Prawie wszyscy użytkownicy mają zainstalowaną przeglądarkę, ale przełączenie kontekstu z aplikacji na przeglądarkę spowodowałoby zauważalne opóźnienie, zwłaszcza na urządzeniach low-end.

  4. korzystanie z niestandardowych kart Chrome: Jest to rozwiązanie, które wybraliśmy, ponieważ nie miało ono żadnych wad wymienionych powyżej.

nasz wybór: Chrome Custom Tabs

Chrome custom tabs (CCT) jest częścią przeglądarki Chrome, która integruje się z platformą Android, aby umożliwić aplikacjom otwieranie stron internetowych w lekkim procesie. CCT otwiera się szybciej niż przeglądarka i, jeśli jest wstępnie załadowany za pomocą rozgrzewki, jest potencjalnie nawet szybszy niż Widok sieci Web. Mimo że nadal działa Javascript, jest w swoim własnym procesie, co uniemożliwia aplikacjom uruchamianie złośliwego kodu. Ponadto interfejs CCT zapewnia pasek akcji, który pokazuje adres URL ładowanej strony, a także ikonę blokady weryfikacji SSL dla bezpiecznych stron. To uspokaja użytkowników, że wyświetlana jest właściwa strona.

alt

chociaż nie wszyscy użytkownicy mają zainstalowaną Chrome, zdecydowana większość ma. Dla tych, którzy tego nie robią, używamy metody awaryjnej przeglądarki opisanej powyżej (opcja 3); Poza dodaniem jednej linii kodu, otrzymujemy rezerwę za darmo od CCT. Jak wspomniano wcześniej, przeglądarka nie jest idealnym doświadczeniem użytkownika ze względu na opóźnienie, ale utrzymuje wysoki poziom bezpieczeństwa, którego wymaga Plaid.

opracowując rozwiązanie CCT, napotkaliśmy kilka komplikacji i rozwiązaliśmy je:

  • pobieranie danych o zdarzeniach

  • Odzyskiwanie wyniku końcowego

  • kontrolowanie czynności WTC &

pobieranie danych zdarzeń

gdy użytkownik porusza się między ekranami w łączu, następuje przekierowanie i dane są dostarczane programistom w parametrach URL.

alt

te informacje o przekierowaniu są cenne dla programistów, ponieważ pomagają im zrozumieć zachowania użytkowników. Gdy CCT działa w swoim własnym procesie i nie zapewnia przekierowania zwrotnego, informacje te byłyby zwykle niedostępne, co sprawiłoby, że nasz bezpieczny zestaw SDK byłby mniej funkcjonalny dla programistów niż ich niestandardowe implementacje WebView.

aby dostarczyć te informacje z CCT, zamiast tego zarejestrowaliśmy zdarzenia przekierowania na serwerze w magazynie danych Redis. Kiedy SDK otwiera Link, wywołuje Bootstrap do naszych serwerów, które zapewniają wybrany przez nas identyfikator kanału użytkownika i tajny klucz. Następnie zestaw SDK tworzy obiekt roboczy o zasięgu aplikacji, który przeszukuje serwer za pomocą strumienia interwałowego RX. Przy każdym wywołaniu ankietowym udostępniamy serwerowi identyfikator kanału, klucz tajny i identyfikator uuid ostatniego zdarzenia (lub null), aby uzyskać najnowsze wydarzenia.

1
2
3
4
5
6
7
8
9
10
11
12

obserwowalne.interwał (interval, TimeUnit.Sekund)
.subscribeOn(bułg.obliczenia())
.observeOn (AndroidSchedulers.mainThread())
.flatMapSingle (makeNetworkCall())
.Subskrybuj(
{
// Obsługa wiadomości
},
{
// Obsługa błędów
})

framework Android może zabić każdy proces, w tym aplikację przy użyciu SDK Plaid. Ponieważ obiekt worker jest powiązany z aplikacją, spowoduje to zatrzymanie workera. Jeśli użytkownik kontynuował przepływ (pomyślnie lub bezskutecznie) SDK wykonałby ostateczne połączenie do kanału i otrzymałby Pozostałe zdarzenia. Zdarzenia zostaną utracone tylko wtedy, gdy użytkownik przerwał przepływ i siła zabiła aplikację.

pobieranie wyniku końcowego

podobnie jak przekazywanie danych o zdarzeniach do klientów, Link używa adresu URL do sygnalizowania, że użytkownik zakończył przepływ. Odpowiedni adres URL zawiera niezbędne dane, takie jak klucz publiczny lub kod błędu.

ponieważ nie możemy uzyskać dostępu do adresu URL za pomocą CCT, zapisaliśmy końcowy wynik w Redis z tym samym ID kanału. Chociaż oznacza to, że nasz pracownik sondażu będzie wiedział, kiedy Link skończy, nie ma gwarancji, że pracownik będzie nadal żył. Nawet jeśli był żywy, użytkownik może czekać na następne wywołanie ankietowe, aby uzyskać wynik, co może trwać kilka sekund.

aby upewnić się, że wynik zostanie dostarczony w odpowiednim czasie, używamy głębokiego linku do ponownego otwarcia zestawu SDK. Głębokie łącze jest tworzone przy użyciu identyfikatora aplikacji, który musi być powiązany z tajemnicą klienta i umieszczony na białej liście na pulpicie programisty. To, plus fakt, że tylko jedna aplikacja na urządzeniu może mieć ten sam identyfikator aplikacji, zapewnia, że żadne inne aplikacje nie przechwycą przekierowania. Następnie aplikacja internetowa Link tworzy intent URI, który jest uruchamiany na końcu przepływu łącza.

1
2

intent: / / redirect / #Intent; scheme=plaid;package = $packageName; end;

nasz zestaw SDK zawiera filtr intencyjny do obsługi URI, dzięki czemu aplikacja otwiera się ponownie i natychmiast wykonuje połączenie bezpośrednio do kanału.

1
2
3
4
5
6
7
8
9
10
11

<intent-filter>
<action android: name= " android.intencja.akcja.Widok" />
<Kategoria android: name= " android.intencja.Kategoria.DEFAULT" />
<Kategoria android: name= " android.intencja.Kategoria.PRZEGLĄDALNE" />
<data
android: host="redirect"
android:scheme= "plaid" />
</intent-filter>

kontrolowanie CCT

CCT nie ma interfejsów dla aplikacji do:

  • nasłuchuj, kiedy użytkownik zamknie aktywność

  • Wykryj, gdy użytkownik kliknął opcję „Otwórz w przeglądarce”

  • Wymuś zamknięcie

udało nam się obejść wszystkie te niedociągnięcia.

najpierw, aby nasłuchać, gdy użytkownik zamyka aktywność, otwieramy CCT za pomocą startActivityForResult i przekazujemy mu kod żądania. Jeśli użytkownik zamknie CCT za pomocą X w lewym górnym rogu przycisku Wstecz systemu, wywołanie zwrotne onActivityResult zostanie wywołane z dostarczonym przez nas kodem żądania i kodem wyniku aktywności.RESULT_CANCELED. Intencja danych nie zawiera żadnych informacji, ale możemy wykonać ostateczne połączenie z kanałem, aby uzyskać Pozostałe zdarzenia. Następnie przekazujemy je do aplikacji klienckiej i zwracamy obiekt LinkCancellation, sygnalizując, że łącze zostało celowo zamknięte przez użytkownika.

następnie potencjalną troską o wykrycie, gdy użytkownik kliknął „Otwórz w przeglądarce”, jest to, że użytkownik może przejść przez cały przepływ w oddzielnej aplikacji, a mianowicie przeglądarce. Nie stanowi to dla nas problemu, ponieważ systemy ankiet i intencji nadal działają w ten sam sposób i nadal możemy uzyskać potrzebne dane.

wreszcie, gdy użytkownik zakończy pomyślnie przepływ i zostanie uruchomiony zamiar wyniku, proces CCT pozostanie otwarty i na liście zadań użytkownika. Ten proces fantomowy byłby nie tylko marnotrawstwem, ale może również być mylący dla użytkownika po naciśnięciu przycisku systemowego „ostatnie zadania”. Dlatego potrzebujemy sposobu, aby zmusić WTC do zamknięcia po zakończeniu przepływu.

w tym celu użyliśmy wzorca pokazanego w Bibliotece OpenID AppAuth dla Androida. Zamiast obsługiwać wynik w aktywności, która otwiera Link, umieszczamy filtr intencji na osobnej aktywności. To drugie działanie obsługuje wszystkie przekierowania z aplikacji internetowej, które obejmują: pomyślne ukończenie, błędy zamykające przepływ, przekierowania OAuth lub App-to-App oraz ogólne błędy systemowe. Działanie następnie przekazuje dane z powrotem do działania otwierającego za pomocą intencji z intencją.FLAG_ACTIVITY_SINGLE_TOP i Intent.FLAG_ACTIVITY_CLEAR_TOP flags. Używane razem, usuwają wszystko na stosie nad czynnością otwarcia, w tym CCT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

val intent = Intent (activity, LinkActivity:: class.java)
when (state) {
is RedirectState.ChromeCustomTabsComplete -> {
intencja.putExtra (LINK_CHROME_CUSTOM_TABS_COMPLETE_REDIRECT, true)
intent.putExtra(LINK_RESULT_CODE, state.resultCode)
intent.putExtra(LINK_RESULT, state.result)
}
is RedirectState.UserInitiatedChromeCustomTabsViewClose -> {
intent.putExtra(LINK_CHROME_CUSTOM_TABS_USER_CLOSE_REDIRECT, true)
}
is RedirectState.OAuth -> {
intent.putExtra(LINK_OAUTH_REDIRECT, true)
intent.putExtra(LINK_OAUTH_STATE_ID, state.oauthStateId)
}
is RedirectState.RedirectError ->
intent.putExtra (LINK_REDIRECT_ERROR, true)
}
intencja.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP lub Intent.FLAG_ACTIVITY_CLEAR_TOP
return intent

alt

końcowe przemyślenia na temat CCT

aby zapewnić bezpieczne, piaskowcowe środowisko niedostępne w WebViews lub natywnych przepływach, CCT jest realnym rozwiązaniem. Jest łatwy w integracji dla programistów i zapewnia lepsze wrażenia użytkownika niż otwieranie okien przeglądarki dzięki swojej lekkiej naturze i szybkości.

charakter piaskownicy CCT i ograniczone API oznaczają, że nie jest bez wad. Słuchanie przekierowań URL, uzyskiwanie ostatecznych wyników i kontrolowanie procesu CCT wymagało od nas kreatywnych rozwiązań. Rozwiązania te opierały się na zrozumieniu wbudowanych funkcji Androida, zwłaszcza intent framework.

korzyści dla programistów i konsumentów były warte wymaganego wysiłku i zalecamy używanie CCT w innych aplikacjach i zestawach SDK w celu szybkiej i bezpiecznej integracji. Co więcej, możesz skorzystać z wskazówek podanych tutaj, aby poprawić wrażenia użytkownika (i programisty).

jeśli jesteś zainteresowany rozwiązywaniem unikalnych problemów, z których skorzystają tysiące programistów i miliony konsumentów, odwiedź naszą stronę kariery.

You might also like

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.