Blockera klartext i Android-appar utan att förlita dig på en VPN
Klartext i nyttolasten och klartext på vägen är två olika problem. Lös det första i appen och det andra med en tunnel eller en enhetspolicy.
Två helt olika saker kallas att blockera klartext på Android. Det ena är en policy inuti en app som beordrar appens egen nätverksstack att avvisa vanlig HTTP. Det andra är en ordning på enhetsnivå som försöker skydda allt på telefonen på en gång, vanligtvis genom att leda trafiken genom en VPN. De löser olika problem, och det andra kan inte reparera det första: en tunnel skyddar sträckan mellan telefonen och utgången, medan en app som talar HTTP fortfarande talar HTTP med allt som ligger bakom den utgången.
Två problem under ett namn
Det första problemet är nyttolasten: appen skriver inloggningsuppgifter eller token i en begäran som inte är krypterad hela vägen, så varje hopp som kan se den kan läsa den. Det andra är vägen: appen kan vara helt korrekt, och du vill ändå att den lokala Wi-Fi-operatören inte ska lära sig något om var den ansluter. En VPN hanterar det andra och bara det andra.
Den skillnaden avgör vem som äger rättelsen. Nyttolasten tillhör den som levererar appen, eftersom bara den koden bestämmer vilken URL som anropas och om ett certifikat valideras. Vägen tillhör enheten eller nätverket, eftersom det handlar om var paketen reser, inte vad de innehåller.
Vägen ett: appen du kontrollerar
Om du levererar appen är rättelsen ett transportbeslut plus en policy som genomdriver det. Rikta varje slutpunkt mot HTTPS, håll validering av värdnamn och certifikat på, och ta bort reservvägen med vanlig HTTP i stället för att lämna den en konfigurationsflagga bort. En omdirigering hjälper inte här: en HTTP-begäran som får en 301 har redan skickat sina rubriker och sin kropp öppet, så inloggningsuppgifter får aldrig resa i antagandet att omdirigeringen skyddar dem.
Från Android 7.0 uttrycker Network Security Configuration policyn. Filen nedan är den minsta användbara versionen: den avvisar klartext överallt om inte ett domänspecifikt undantag säger annat.
<network-security-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>Hänvisa till den resursen från manifestet och läs sedan de undantag som redan finns innan du levererar. En gammal felsökningsdomän eller en SDK-post från en betalningsleverantör kan tyst tillåta klartext igen för värden du försökte skydda.
Två versionsdetaljer är värda att känna till. Appar som riktar sig mot API 28 eller högre avvisar redan klartext som standard, så en app som fortfarande talar vanlig HTTP riktar sig antingen mot en äldre API-nivå eller har ett undantag någonstans. Och när det finns en nätverkssäkerhetskonfiguration avgör inte det äldre manifestattributet android:usesCleartextTraffic frågan längre, och därför verkar det ibland som att ändringen av den flaggan inte gör något.
Vägen två: appen du inte kontrollerar
För en installerad tredjepartsapp kan du inte skriva om dess säkerhetskonfiguration via en användarinställning. De realistiska alternativen är produktens egna kontroller för säker anslutning, ett underhållet alternativ som redan använder TLS, eller en policy för hanterade enheter som begränsar vad enheten får köra. Det är olika åtaganden, och bara det tredje skalar till en flotta.
Nätverksregler är svagare ersättningar än de ser ut. Att bara tillåta port 443 genomdriver inte autentiserad TLS, eftersom många klartextprotokoll kan flyttas till den porten, och att blockera port 80 täcker inte klartext på andra portar. En webbläsares läge med bara HTTPS är också begränsat till den webbläsaren, inte till en separat mejl- eller chattapp på samma telefon.
Att installera ett avlyssningscertifikat för att trafiken ska se krypterad ut är en förändring av förtroende, inte en rättelse. Det ersätter appens serverautentisering med din, och en app som inte validerade certifikat från början repareras inte av det; du har bara flyttat vem som kan läsa strömmen.
Var en VPN hjälper och var den inte gör det
En tunnel är rätt verktyg när kravet är att det lokala nätverket inte ska lära sig något om anslutningen, eller att appen ska nå en privat tjänst som den annars inte når. Den är fel verktyg för att få en HTTP-klient att tala HTTPS, eftersom begäran lämnar tunneln exakt som den kom in.
Android lägger till en praktisk begränsning: plattformen kör bara en VPN-tjänst åt gången. En lokal filtreringsapp som tar den platsen konkurrerar med den fjärrtunnel du faktiskt behöver, och att växla mellan dem är en åtgärd på enhetsnivå snarare än appnivå. Den enda platsen är ett bra skäl att lägga nyttolastpolicyn i appen och behålla tunneln för vägen.
Det enda fallet där de två överlappar är en privat server som du också driver. Där kan en tunnel göra vägen privat även om protokollet fortfarande är klartext, vilket minskar exponeringen men inte ändrar vad nyttolasten är. Behandla det som riskminskning, inte som kryptering av data.
Vad du bör testa innan du kallar det blockerat
Börja med standarden som överraskar folk: en app som riktar sig mot API 28 eller högre borde redan avvisa klartext, så kontrollera målnivån innan du lägger till konfiguration som duplicerar en standard. Testa sedan felet med flit: en begäran till en vanlig HTTP-värd måste misslyckas i stället för att tyst lyckas via en reservväg.
adb shell dumpsys package com.example.app | grep -E 'targetSdk|versionName'
adb logcat | grep -i cleartextFör framgångsfallet, bekräfta att HTTPS-anropet validerar en riktig certifikatkedja och att en proxy med ett ej betrott certifikat avvisas i stället för tolereras. Ett handskakning som lyckas mot vilket certifikat som helst har inte bevisat något om transportsäkerhet.
För en tredjepartsapp, skriv ned den gräns du faktiskt kan genomdriva, vare sig det är en policy för hanterade enheter, en nätverksregel eller ingenting, och säg det i acceptanskriterierna. Android-guiden för säkerhetskonfiguration listar plattformens standarder och vilka komponenter som respekterar policyn, och det är den delen som avgör om din konfiguration överhuvudtaget gör något.