WebViews beveiligen met Chrome Custom Tabs

Plaid stelt vernieuwers in de fintech-ruimte in staat door hen toegang te bieden tot financiële gegevens via een uniforme API. Om eindgebruikers te helpen hun bankgegevens aan fintech-apps te koppelen, ontwikkelde Plaid Link, Een drop-in-module die credential validation, multi-factor authenticatie en foutafhandeling voor elke ondersteunde bank afhandelt.

Android-ontwikkelaars moesten eerder Link-URL ‘ s openen in WebViews. Elke app die wilde Link te gebruiken vereist veel Ontwikkelaar inspanning en, zonder standaardisatie, er waren gebonden aan bugs in sommige van de implementaties. Om de ontwikkelaar ervaring te verbeteren, hebben we onlangs een SDK waardoor de WebView gemakkelijk te integreren in elke app met een paar regels code.

Bovendien zijn WebViews niet volledig veilig voor eindgebruikers die gevoelige informatie invoeren in de Link flow. Om onze SDK zo veilig mogelijk te maken, hebben we het geà mplementeerd met behulp van Chrome aangepaste tabbladen in plaats van Android WebViews. In dit artikel leggen we uit waarom we die beslissing hebben genomen en hoe we de technische problemen hebben overwonnen die we onderweg tegenkwamen.

bij het evalueren van onze opties

als een SDK draait onze code binnen de applicaties van andere ontwikkelaars, en, op zijn beurt, hun applicatieprocessen. Om de Link web app in een WebView uit te voeren, moet Javascript ingeschakeld zijn. Dit opent de deur voor andere apps om kwaadaardige code uit te voeren, zoals het registreren van callbacks die proberen om gebruikersnamen en wachtwoorden te onderscheppen. Bovendien, een kwaadaardige app kan een andere webpagina die de Link stroom nabootst in een phishing-poging te openen.

bij het zoeken naar een oplossing die eenvoudig te integreren is voor ontwikkelaars, intuïtief voor eindgebruikers en veilig, hebben we verschillende opties geëvalueerd:

  1. bouwen van een native link flow: omdat native Link flows zou ook draaien in het proces van een andere app, savvy ontwikkelaars kunnen reflectie gebruiken om onze Input EditTexts te vinden en callbacks te registreren op een manier vergelijkbaar met Javascript in een WebView.

  2. een aparte authenticator-app bouwen: Dit zou een native sandboxed ervaring en zou een ideale ervaring voor eindgebruikers; echter, veel gebruikers zouden niet willen downloaden van een extra app van de Play Store. Dit betekent dat we een noodoplossing nodig hebben voor gebruikers die weigeren de app te downloaden.

  3. link openen in een apart browservenster: dit zou een sandboxed, veilige oplossing zijn. Bijna alle gebruikers hebben een browser geïnstalleerd, maar de context overschakelen van een app naar een browser zou een merkbare vertraging te introduceren, vooral op low-end apparaten.

  4. Chrome aangepaste tabbladen gebruiken: Dit is de oplossing die we hebben gekozen, omdat het geen van de hierboven genoemde nadelen had.

onze keuze: Chrome Custom tabs

Chrome custom tabs (CCT) is een onderdeel van de Chrome-browser die integreert met het Android-framework om apps in staat te stellen websites te openen in een licht proces. CCT opent sneller dan een browser en, indien vooraf geladen via de warming-up call, is mogelijk zelfs sneller dan een WebView. Terwijl het nog steeds draait Javascript, het is in zijn eigen proces, die voorkomt dat apps van het uitvoeren van kwaadaardige code. Bovendien biedt de CCT UI een actiebalk die de URL van de pagina die wordt geladen toont, samen met een SSL-verificatieslotpictogram voor beveiligde pagina ‘ s. Dit verzekert gebruikers dat de juiste pagina wordt getoond.

alt

hoewel niet alle gebruikers hebben Chrome geà nstalleerd, de overgrote meerderheid doen. Voor degenen die dat niet doen, gebruiken we de browser fallback methode hierboven beschreven (optie 3); anders dan het toevoegen van een regel code, krijgen we de fallback gratis van CCT. Zoals eerder opgemerkt, de browser fallback is niet de ideale gebruikerservaring als gevolg van de latency, maar het behoudt wel het hoge niveau van beveiliging die Plaid vereist.

naarmate we de CCT-oplossing ontwikkelden, kwamen we verschillende complicaties tegen en behandelden we deze.:

  • gebeurtenisgegevens ophalen

  • het eindresultaat ophalen

  • controle van de GDT-activiteit &

gebeurtenisgegevens

ophalen wanneer een gebruiker tussen schermen navigeert in Link, vindt een omleiding plaats en worden gegevens verstrekt aan ontwikkelaars in de URL-parameters.

alt

deze redirect informatie is waardevol voor ontwikkelaars, omdat het hen helpt het gedrag van gebruikers te begrijpen. Met CCT draait in zijn eigen proces en niet het verstrekken van een redirect callback, zou deze informatie normaal ontoegankelijk zijn, waardoor onze veilige SDK minder functioneel voor ontwikkelaars dan hun aangepaste WebView implementaties zou maken.

om deze informatie van CCT te leveren, hebben we in plaats daarvan de redirect gebeurtenissen op de server opgenomen in een Redis datastore. Wanneer de SDK Link opent, maakt het een bootstrap call naar onze servers, die een door ons gekozen kanaal-ID per gebruiker en een geheime sleutel bieden. De SDK maakt vervolgens een worker-object met apps, dat de server polls met behulp van een Rx-intervalstream. Bij elke polling call voorzien we de server van het kanaal ID, geheime sleutel, en de laatste gebeurtenis UUID (of null) om de laatste gebeurtenissen te krijgen.

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

waarneembaar.interval (interval, tijdseenheid.Seconden)
.subscribeOn (planners.berekening())
.observeOn (AndroidSchedulers.mainThread())
.flatMapSingle (makeNetworkCall)())
.abonneren(
{
// berichten verwerken
},
{
// fouten verwerken
})

het Android framework kan elk proces te doden, met inbegrip van de app met behulp van Plaid SDK. Aangezien het arbeidersobject aan de aanvraag is gebonden, zou dit ertoe leiden dat de werknemer wordt gestopt. Als de gebruiker doorging met de stroom, (met succes of zonder succes) zou de SDK een laatste oproep naar het kanaal te maken en krijgen de resterende gebeurtenissen. Gebeurtenissen zouden alleen verloren gaan als de gebruiker de stroom afgebroken en kracht doodde de app.

het eindresultaat ophalen

net als het doorgeven van gebeurtenisgegevens aan clients, gebruikt Link de URL om aan te geven dat de gebruiker de stroom heeft voltooid. De relevante URL bevat noodzakelijke gegevens, zoals de openbare sleutel of een foutcode.

omdat we geen toegang hebben tot de URL met CCT, hebben we het eindresultaat opgeslagen in Redis met hetzelfde kanaal-ID. Terwijl dit betekent dat onze stembureau werknemer zou weten wanneer Link is voltooid, zou er geen garantie dat de werknemer nog in leven zou zijn. Zelfs als het zou leven, de gebruiker kan hebben om te wachten tot de volgende polling oproep voor het resultaat te leveren, die een lange paar seconden kan zijn.

om ervoor te zorgen dat een resultaat tijdig wordt geleverd, gebruiken we een deep link om de SDK te heropenen. De diepe link wordt geconstrueerd met behulp van de App-ID van de applicatie, die moet worden geassocieerd met de client geheim en whitelisted op de ontwikkelaar dashboard. Dit, plus het feit dat slechts één app op een apparaat dezelfde app-ID kan hebben, zorgt ervoor dat er geen andere apps onderscheppen de redirect. De Link web app bouwt vervolgens een intent URI, die wordt afgevuurd aan het einde van de Link flow.

1
2

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

onze SDK bevat een intentiefilter om de URI af te handelen, zodat de toepassing opnieuw wordt geopend en direct naar het kanaal wordt gebeld.

1
2
3
4
5
6
7
8
9
10
11

<intent-filter>
<action android:name="android.bedoeling.actie.Beeld" />
<categorie android: Naam = " android.bedoeling.categorie.Standaard" />
<categorie android: Naam = " android.bedoeling.categorie.BLADERBAAR" />
<data
android: host= "redirect"
android:scheme="plaid" />
</intent-filter>

het Beheersen van CCT

CCT ontbreekt interfaces voor de app:

  • luister wanneer de gebruiker sluit de activiteit

  • detecteren wanneer de gebruiker klikte op de “Open in Browser” optie

  • geforceerd te sluiten

We hebben met succes gewerkt rond al deze tekortkomingen.

eerst, om te luisteren naar wanneer de gebruiker de activiteit sluit, openen we CCT met behulp van startActivityForResult en geven het een aanvraagcode door. Als de gebruiker CCT sluit met behulp van de X in de linkerbovenhoek van de systeem terug knop, wordt de onactivityresult callback geactiveerd met de aanvraagcode die we hebben verstrekt en een resultaatcode van activiteit.RESULT_CANCELED. De data intent bevat geen informatie, maar we kunnen een laatste oproep doen naar het kanaal om de resterende gebeurtenissen te krijgen. We geven ze vervolgens door aan de client-app en retourneren een linkcancellation-object, waarmee wordt aangegeven dat de Link opzettelijk is gesloten door de gebruiker.

Vervolgens is de potentiële zorg bij het detecteren wanneer de gebruiker op “Open in Browser” heeft geklikt, dat de gebruiker dan de gehele stroom in een afzonderlijke toepassing kan doorlopen, namelijk de browser. Dat is voor ons geen probleem, want de peiling-en intentsystemen blijven op dezelfde manier werken en we kunnen nog steeds de benodigde gegevens verkrijgen.

ten slotte, wanneer de gebruiker de flow met succes voltooit en de resultaatintentie wordt afgevuurd, blijft het CCT-proces open en staat het in de takenlijst van de gebruiker. Dit fantoomproces zou niet alleen verspillend zijn, maar kan ook verwarrend zijn voor een gebruiker wanneer hij op de “recente taken” – systeemknop drukt. Daarom hebben we een manier nodig om CCT te dwingen om te sluiten wanneer de stroom is voltooid.

om dit te doen, gebruikten we het patroon dat wordt getoond in de OpenId AppAuth voor Android bibliotheek. In plaats van het resultaat af te handelen in de activiteit die Link opent, plaatsen we het doelfilter op een aparte activiteit. Deze tweede activiteit behandelt alle omleidingen van de web app, waaronder: succesvolle voltooiingen, fouten die de stroom te sluiten, oAuth of App-to-App omleidingen, en algemene systeemfouten. De activiteit stuurt vervolgens de gegevens terug naar de openingsactiviteit met behulp van een intentie met de intentie.FLAG_ACTIVITY_SINGLE_TOP en Intent.FLAG_ACTIVITY_CLEAR_TOP vlaggen. Samen gebruikt, wissen ze alles op de stapel boven de openingsactiviteit, inclusief CCT.

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

val intentie = Intent(activiteit, LinkActivity::klasse.java)
wanneer (Status) {
wordt omgeleid.ChromeCustomTabsComplete -> {
opzet.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) )
}
opzet.flags = Intentie.FLAG_ACTIVITY_SINGLE_TOP of Intent.FLAG_ACTIVITY_CLEAR_TOP
return intent

alt

laatste gedachten over CCT

om een veilige, sandboxed-ervaring te bieden die niet beschikbaar is in WebViews of native flows, is CCT een haalbare oplossing. Het is gemakkelijk te integreren met voor ontwikkelaars en biedt een betere gebruikerservaring dan het openen van browservensters dankzij de lichtgewicht aard en snelheid. Het sandboxed karakter van het CCT en de beperkte API betekenen dat het niet zonder nadelen is. Het luisteren naar URL-omleidingen, het verkrijgen van definitieve resultaten en het beheersen van het CCT-proces vereisten ons allemaal om met creatieve oplossingen te komen. Deze oplossingen vertrouwden op een goed begrip van de ingebouwde functies van Android, met name het intent framework.

de voordelen voor ontwikkelaars en consumenten waren de moeite waard en we raden het gebruik van CCT in andere apps en SDK ‘ s aan voor een snelle en veilige integratie. Bovendien kunt u gebruik maken van de tips hier om de gebruiker (en ontwikkelaar) ervaring te verbeteren.

als u geïnteresseerd bent in het oplossen van unieke problemen die zullen worden gebruikt door duizenden ontwikkelaars en miljoenen consumenten, bezoek dan onze carrièrepagina.

You might also like

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.