Dwie zupełnie różne rzeczy nazywa się blokowaniem czystego tekstu na Androidzie. Jedna to polityka wewnątrz aplikacji, która każe jej własnemu stosowi sieciowemu odrzucać zwykły HTTP. Druga to rozwiązanie na poziomie urządzenia, które próbuje ochronić wszystko na telefonie naraz, zwykle kierując ruch przez VPN. Rozwiązują różne problemy, a druga nie naprawi pierwszej: tunel chroni odcinek między telefonem a wyjściem, podczas gdy aplikacja mówiąca HTTP nadal mówi HTTP z wszystkim, co jest za tym wyjściem.

Dwa problemy pod jedną nazwą

Pierwszy problem to ładunek: aplikacja zapisuje dane uwierzytelniające lub tokeny w żądaniu, które nie jest szyfrowane od końca do końca, więc każdy skok, który je widzi, może je odczytać. Drugi to ścieżka: aplikacja może być całkowicie poprawna, a ty nadal chcesz, aby lokalny operator Wi-Fi nie dowiedział się nic o tym, gdzie się łączy. VPN zajmuje się drugim i tylko drugim.

Ta różnica decyduje, do kogo należy poprawka. Ładunek należy do tego, kto dostarcza aplikację, bo tylko ten kod decyduje, który adres URL jest wywoływany i czy certyfikat jest weryfikowany. Ścieżka należy do urządzenia lub sieci, bo chodzi o to, gdzie podróżują pakiety, a nie co zawierają.

Ścieżka pierwsza: aplikacja, którą kontrolujesz

Jeśli dostarczasz aplikację, poprawką jest decyzja o transporcie plus polityka, która ją egzekwuje. Skieruj każdy punkt końcowy na HTTPS, pozostaw włączoną weryfikację nazwy hosta i certyfikatu, i usuń awaryjne przejście na zwykły HTTP, zamiast zostawiać je o jedną flagę konfiguracji dalej. Przekierowanie tu nie pomaga: żądanie HTTP, które otrzymuje 301, wysłało już nagłówki i treść otwarcie, więc dane uwierzytelniające nigdy nie mogą podróżować w założeniu, że przekierowanie je ochroni.

Od Androida 7.0 politykę wyraża Network Security Configuration. Plik poniżej jest najmniejszą użyteczną wersją: odrzuca czysty tekst wszędzie, chyba że wyjątek dla konkretnej domeny mówi inaczej.

<network-security-config>
    <base-config cleartextTrafficPermitted="false" />
</network-security-config>

Odwołaj się do tego zasobu z manifestu, a potem przeczytaj już istniejące wyjątki przed dostarczeniem. Stara domena debugowania lub wpis SDK dostawcy płatności mogą po cichu ponownie zezwolić na czysty tekst dla hosta, który próbowałeś chronić.

Warto znać dwa szczegóły wersji. Aplikacje kierowane na API 28 lub nowsze już domyślnie odrzucają czysty tekst, więc aplikacja, która nadal mówi zwykłym HTTP, albo celuje w starszy poziom API, albo ma gdzieś wyjątek. A gdy istnieje konfiguracja zabezpieczeń sieci, starszy atrybut manifestu android:usesCleartextTraffic nie decyduje już o tej sprawie, dlatego zmiana tej flagi czasem wygląda, jakby nic nie robiła.

Ścieżka druga: aplikacja, której nie kontrolujesz

Dla zainstalowanej aplikacji innej firmy nie możesz przepisać jej konfiguracji zabezpieczeń ustawieniem użytkownika. Realistyczne opcje to własne mechanizmy bezpiecznego połączenia produktu, utrzymywana alternatywa, która już używa TLS, albo polityka zarządzanego urządzenia ograniczająca to, co urządzenie może uruchamiać. To różne zobowiązania i tylko trzecie skaluje się na całą flotę.

Reguły sieciowe są słabszymi zamiennikami, niż się wydają. Zezwolenie tylko na port 443 nie wymusza uwierzytelnionego TLS, bo wiele protokołów czystego tekstu można przenieść na ten port, a blokowanie portu 80 nie obejmuje czystego tekstu na innych portach. Tryb tylko HTTPS przeglądarki też jest ograniczony do tej przeglądarki, a nie do osobnej aplikacji poczty lub czatu na tym samym telefonie.

Zainstalowanie certyfikatu przechwytującego, aby ruch wyglądał na szyfrowany, jest zmianą zaufania, nie poprawką. Zastępuje uwierzytelnianie serwera aplikacji twoim, a aplikacji, która od początku nie weryfikowała certyfikatów, to nie naprawia; przesunąłeś tylko to, kto może czytać strumień.

Gdzie VPN pomaga, a gdzie nie

Tunel jest właściwym narzędziem, gdy wymaganiem jest, aby lokalna sieć nie dowiedziała się nic o połączeniu, albo aby aplikacja dotarła do prywatnej usługi, do której inaczej nie dotrze. Jest niewłaściwym narzędziem do zmuszania klienta HTTP, by mówił HTTPS, bo żądanie opuszcza tunel dokładnie takie, jakie do niego weszło.

Android dodaje praktyczne ograniczenie: platforma uruchamia tylko jedną usługę VPN naraz. Lokalna aplikacja filtrująca, która zajmuje to miejsce, konkuruje z tunelem zdalnym, którego naprawdę potrzebujesz, a przełączanie między nimi jest operacją na poziomie urządzenia, nie aplikacji. To jedno miejsce to dobry powód, by politykę ładunku trzymać w aplikacji, a tunel zachować dla ścieżki.

Jedyny przypadek, w którym oba się nakładają, to prywatny serwer, którym sam zarządzasz. Tam tunel może uczynić ścieżkę prywatną, choć protokół to nadal czysty tekst, co zmniejsza ekspozycję, ale nie zmienia tego, czym jest ładunek. Traktuj to jako redukcję ryzyka, nie jako szyfrowanie danych.

Co przetestować, zanim nazwiesz to zablokowanym

Zacznij od domyślnego ustawienia, które zaskakuje ludzi: aplikacja kierowana na API 28 lub nowsze powinna już odrzucać czysty tekst, więc sprawdź poziom docelowy, zanim dodasz konfigurację dublującą ustawienie domyślne. Potem celowo przetestuj przypadek awarii: żądanie do zwykłego hosta HTTP musi się nie powieść, a nie po cichu udać się przez przejście awaryjne.

adb shell dumpsys package com.example.app | grep -E 'targetSdk|versionName'
adb logcat | grep -i cleartext

W przypadku sukcesu potwierdź, że wywołanie HTTPS weryfikuje prawdziwy łańcuch certyfikatów i że proxy z niezaufanym certyfikatem jest odrzucane, a nie tolerowane. Uścisk dłoni, który udaje się z dowolnym certyfikatem, niczego nie dowiódł o bezpieczeństwie transportu.

Dla aplikacji innej firmy zapisz granicę, którą naprawdę możesz wyegzekwować, czy to polityka zarządzanego urządzenia, reguła sieciowa, czy nic, i powiedz to w kryteriach akceptacji. przewodnik konfiguracji zabezpieczeń Androida wymienia ustawienia domyślne platformy i to, które komponenty przestrzegają polityki, i właśnie ta część decyduje, czy twoja konfiguracja robi cokolwiek.

Powiązane artykuły