Android Applications Basics

Wsparcie dla HackTricks

Grupa Try Hard Security


Model bezpieczeństwa Androida

Istnieją dwie warstwy:

  • OS, który utrzymuje zainstalowane aplikacje w izolacji od siebie.

  • sama aplikacja, która pozwala deweloperom udostępniać określone funkcjonalności i konfigurować możliwości aplikacji.

Separacja UID

Każdej aplikacji przypisany jest konkretny identyfikator użytkownika (User ID). Dzieje się to podczas instalacji aplikacji, aby aplikacja mogła interagować tylko z plikami należącymi do jej identyfikatora użytkownika lub z plikami współdzielonymi. Dlatego tylko sama aplikacja, niektóre komponenty systemu operacyjnego i użytkownik root mogą uzyskać dostęp do danych aplikacji.

Współdzielenie UID

Dwie aplikacje mogą być skonfigurowane do używania tego samego UID. Może to być przydatne do dzielenia się informacjami, ale jeśli jedna z nich zostanie skompromitowana, dane obu aplikacji będą skompromitowane. Dlatego takie zachowanie jest odradzane. Aby współdzielić ten sam UID, aplikacje muszą zdefiniować tę samą wartość android:sharedUserId w swoich manifestach.

Sandbox

Sandbox aplikacji Android pozwala na uruchamianie każdej aplikacji jako osobnego procesu pod osobnym identyfikatorem użytkownika. Każdy proces ma swoją własną maszynę wirtualną, więc kod aplikacji działa w izolacji od innych aplikacji. Od Androida 5.0(L) SELinux jest egzekwowany. Zasadniczo, SELinux odmawia wszelkich interakcji procesów, a następnie tworzy polityki, aby zezwolić tylko na oczekiwane interakcje między nimi.

Uprawnienia

Kiedy instalujesz aplikację i prosi o uprawnienia, aplikacja prosi o uprawnienia skonfigurowane w elementach uses-permission w pliku AndroidManifest.xml. Element uses-permission wskazuje nazwę żądanego uprawnienia w atrybucie name. Ma również atrybut maxSdkVersion, który przestaje prosić o uprawnienia w wersjach wyższych niż ta określona. Zauważ, że aplikacje na Androida nie muszą prosić o wszystkie uprawnienia na początku, mogą również prosić o uprawnienia dynamicznie, ale wszystkie uprawnienia muszą być zadeklarowane w manifeście.

Kiedy aplikacja udostępnia funkcjonalność, może ograniczyć dostęp tylko do aplikacji, które mają określone uprawnienie. Element uprawnienia ma trzy atrybuty:

  • nazwa uprawnienia

  • Atrybut permission-group, który pozwala na grupowanie powiązanych uprawnień.

  • poziom ochrony, który wskazuje, jak przyznawane są uprawnienia. Istnieją cztery typy:

  • Normalne: Używane, gdy nie ma znanych zagrożeń dla aplikacji. Użytkownik nie musi ich zatwierdzać.

  • Niebezpieczne: Wskazuje, że uprawnienie przyznaje żądającej aplikacji pewien podwyższony dostęp. Użytkownicy są proszeni o ich zatwierdzenie.

  • Podpis: Tylko aplikacje podpisane tym samym certyfikatem, co ten eksportujący komponent, mogą otrzymać uprawnienie. To najsilniejszy typ ochrony.

  • PodpisLubSystem: Tylko aplikacje podpisane tym samym certyfikatem, co ten eksportujący komponent lub aplikacje działające z dostępem na poziomie systemu mogą otrzymać uprawnienia.

Aplikacje wstępnie zainstalowane

Te aplikacje zazwyczaj znajdują się w katalogach /system/app lub /system/priv-app i niektóre z nich są optymalizowane (możesz nawet nie znaleźć pliku classes.dex). Te aplikacje warto sprawdzić, ponieważ czasami działają zbyt wieloma uprawnieniami (jako root).

  • Te dostarczane z AOSP (Android OpenSource Project) ROM

  • Dodane przez producenta urządzenia

  • Dodane przez dostawcę telefonu komórkowego (jeśli zakupione od nich)

Rootowanie

Aby uzyskać dostęp root do fizycznego urządzenia z Androidem, zazwyczaj musisz wykorzystać 1 lub 2 luki które zazwyczaj są specyficzne dla urządzenia i wersji. Gdy exploit zadziała, zazwyczaj binarny plik Linux su jest kopiowany do lokalizacji określonej w zmiennej środowiskowej PATH użytkownika, takiej jak /system/xbin.

Gdy binarny plik su jest skonfigurowany, używana jest inna aplikacja Android do interakcji z binarnym plikiem su i przetwarzania żądań dostępu root, takich jak Superuser i SuperSU (dostępne w sklepie Google Play).

Zauważ, że proces rootowania jest bardzo niebezpieczny i może poważnie uszkodzić urządzenie.

ROM-y

Możliwe jest zastąpienie systemu operacyjnego instalując niestandardowe oprogramowanie. Dzięki temu można wydłużyć użyteczność starego urządzenia, obejść ograniczenia oprogramowania lub uzyskać dostęp do najnowszego kodu Androida. OmniROM i LineageOS to dwa z najpopularniejszych oprogramowań do użycia.

Zauważ, że nie zawsze jest konieczne rootowanie urządzenia, aby zainstalować niestandardowe oprogramowanie. Niektórzy producenci pozwalają na odblokowanie swoich bootloaderów w dobrze udokumentowany i bezpieczny sposób.

Implikacje

Gdy urządzenie jest zrootowane, każda aplikacja może żądać dostępu jako root. Jeśli złośliwa aplikacja go uzyska, będzie miała dostęp do prawie wszystkiego i będzie mogła uszkodzić telefon.

Podstawy aplikacji na Androida

  • Format aplikacji na Androida określany jest jako format pliku APK. Jest to zasadniczo plik ZIP (zmieniając rozszerzenie pliku na .zip, zawartość można wyodrębnić i przeglądać).

  • Zawartość APK (nie wyczerpująca)

  • AndroidManifest.xml

  • resources.arsc/strings.xml

  • resources.arsc: zawiera skompilowane zasoby, takie jak binarny XML.

  • res/xml/files_paths.xml

  • META-INF/

  • Tutaj znajduje się certyfikat!

  • classes.dex

  • Zawiera bajtkod Dalvik, reprezentujący skompilowany kod Java (lub Kotlin), który aplikacja wykonuje domyślnie.

  • lib/

  • Zawiera biblioteki natywne, segregowane według architektury CPU w podkatalogach.

  • armeabi: kod dla procesorów opartych na ARM

  • armeabi-v7a: kod dla procesorów ARMv7 i wyższych

  • x86: kod dla procesorów X86

  • mips: kod tylko dla procesorów MIPS

  • assets/

  • Przechowuje różne pliki potrzebne aplikacji, potencjalnie w tym dodatkowe biblioteki natywne lub pliki DEX, czasami używane przez autorów złośliwego oprogramowania do ukrywania dodatkowego kodu.

  • res/

  • Zawiera zasoby, które nie są skompilowane w resources.arsc

Dalvik i Smali

W rozwoju Androida, Java lub Kotlin jest używane do tworzenia aplikacji. Zamiast używać JVM jak w aplikacjach desktopowych, Android kompiluje ten kod do bajtkodu Dalvik Executable (DEX). Wcześniej, maszyna wirtualna Dalvik obsługiwała ten bajtkod, ale teraz, w nowszych wersjach Androida, przejmuje go Android Runtime (ART).

W inżynierii odwrotnej, Smali staje się kluczowy. To czytelna dla człowieka wersja bajtkodu DEX, działająca jak język asemblera, tłumacząc kod źródłowy na instrukcje bajtkodu. Smali i baksmali odnoszą się do narzędzi asemblera i deasemblacji w tym kontekście.

Intencje

Intencje są głównym sposobem, w jaki aplikacje Android komunikują się między swoimi komponentami lub z innymi aplikacjami. Te obiekty wiadomości mogą również przenosić dane między aplikacjami lub komponentami, podobnie jak żądania GET/POST są używane w komunikacji HTTP.

Tak więc intencja to zasadniczo wiadomość, która jest przekazywana między komponentami. Intencje mogą być kierowane do konkretnych komponentów lub aplikacji, lub mogą być wysyłane bez konkretnego odbiorcy. Aby uprościć, intencja może być używana:

  • Do uruchamiania aktywności, zazwyczaj otwierając interfejs użytkownika dla aplikacji

  • Jako transmisje, aby informować system i aplikacje o zmianach

  • Do uruchamiania, zatrzymywania i komunikowania się z usługą w tle

  • Do uzyskiwania dostępu do danych za pośrednictwem ContentProviders

  • Jako wywołania zwrotne do obsługi zdarzeń

Jeśli są podatne, intencje mogą być używane do przeprowadzania różnych ataków.

Filtr intencji

Filtry intencji definiują jak aktywność, usługa lub odbiornik transmisji mogą interagować z różnymi typami intencji. Zasadniczo opisują one możliwości tych komponentów, takie jak jakie akcje mogą wykonywać lub jakie rodzaje transmisji mogą przetwarzać. Główne miejsce do deklarowania tych filtrów to plik AndroidManifest.xml, chociaż dla odbiorników transmisji, kodowanie ich również jest opcją.

Filtry intencji składają się z kategorii, akcji i filtrów danych, z możliwością dodania dodatkowych metadanych. Ta konfiguracja pozwala komponentom obsługiwać konkretne intencje, które pasują do zadeklarowanych kryteriów.

Krytycznym aspektem komponentów Androida (aktywności/usługi/dostawcy treści/odbiorniki transmisji) jest ich widoczność lub status publiczny. Komponent jest uważany za publiczny i może interagować z innymi aplikacjami, jeśli jest exported z wartością true lub jeśli dla niego zadeklarowany jest filtr intencji w manifeście. Istnieje jednak sposób, aby deweloperzy wyraźnie zachowali te komponenty jako prywatne, zapewniając, że nie będą interagować z innymi aplikacjami niezamierzenie. Osiąga się to poprzez ustawienie atrybutu exported na false w ich definicjach manifestu.

Ponadto, deweloperzy mają możliwość dalszego zabezpieczenia dostępu do tych komponentów, wymagając określonych uprawnień. Atrybut permission może być ustawiony, aby wymusić, że tylko aplikacje z wyznaczonym uprawnieniem mogą uzyskać dostęp do komponentu, dodając dodatkową warstwę bezpieczeństwa i kontroli nad tym, kto może z nim interagować.

<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>

Implicit Intents

Intencje są programowo tworzone za pomocą konstruktora Intent:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

The Action wcześniej zadeklarowanego zamiaru to ACTION_SEND, a Extra to mailto Uri (Extra to dodatkowe informacje, których oczekuje zamiar).

Ten zamiar powinien być zadeklarowany w manifeście, jak w następującym przykładzie:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Filtr intencji musi pasować do akcji, danych i kategorii, aby odebrać wiadomość.

Proces "rozwiązywania intencji" określa, która aplikacja powinna odebrać każdą wiadomość. Proces ten uwzględnia atrybut priorytetu, który można ustawić w deklaracji filtru intencji, a ten z wyższym priorytetem zostanie wybrany. Ten priorytet można ustawić w zakresie od -1000 do 1000, a aplikacje mogą używać wartości SYSTEM_HIGH_PRIORITY. Jeśli wystąpi konflikt, pojawia się okno "wyboru", aby użytkownik mógł zdecydować.

Eksplicytne intencje

Eksplicytna intencja określa nazwę klasy, którą celuje:

Intent downloadIntent = new (this, DownloadService.class):

W innych aplikacjach, aby uzyskać dostęp do wcześniej zadeklarowanego zamiaru, możesz użyć:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Pending Intents

Te pozwalają innym aplikacjom podejmować działania w imieniu twojej aplikacji, używając tożsamości i uprawnień twojej aplikacji. Konstruując Pending Intent, należy określić intencję i akcję do wykonania. Jeśli zadeklarowana intencja nie jest wyraźna (nie określa, która intencja może ją wywołać), złośliwa aplikacja mogłaby wykonać zadeklarowaną akcję w imieniu aplikacji ofiary. Co więcej, jeśli akcja nie jest określona, złośliwa aplikacja będzie mogła wykonać dowolną akcję w imieniu ofiary.

Broadcast Intents

W przeciwieństwie do poprzednich intencji, które są odbierane tylko przez jedną aplikację, intencje rozgłoszeniowe mogą być odbierane przez wiele aplikacji. Jednak od wersji API 14, możliwe jest określenie aplikacji, która powinna otrzymać wiadomość, używając Intent.setPackage.

Alternatywnie, możliwe jest również określenie uprawnienia podczas wysyłania rozgłoszenia. Aplikacja odbierająca będzie musiała mieć to uprawnienie.

Istnieją dwa typy rozgłoszeń: Normalne (asynchroniczne) i Zamówione (synchronizowane). Kolejność opiera się na skonfigurowanym priorytecie w elemencie odbiorcy. Każda aplikacja może przetwarzać, przekazywać lub odrzucać rozgłoszenie.

Możliwe jest wysłanie rozgłoszenia za pomocą funkcji sendBroadcast(intent, receiverPermission) z klasy Context. Możesz również użyć funkcji sendBroadcast z LocalBroadCastManager, która zapewnia, że wiadomość nigdy nie opuszcza aplikacji. Używając tego, nie będziesz nawet musiał eksportować komponentu odbiorcy.

Sticky Broadcasts

Ten rodzaj rozgłoszeń może być dostępny długo po ich wysłaniu. Zostały one wycofane w poziomie API 21 i zaleca się nie używać ich. Pozwalają one każdej aplikacji na podsłuchiwanie danych, ale także na ich modyfikację.

Jeśli znajdziesz funkcje zawierające słowo "sticky", takie jak sendStickyBroadcast lub sendStickyBroadcastAsUser, sprawdź wpływ i spróbuj je usunąć.

W aplikacjach Android, deep links są używane do inicjowania akcji (Intencja) bezpośrednio przez URL. Dzieje się to poprzez zadeklarowanie konkretnego schematu URL w obrębie aktywności. Gdy urządzenie z Androidem próbuje uzyskać dostęp do URL z tym schematem, określona aktywność w aplikacji jest uruchamiana.

Schemat musi być zadeklarowany w pliku AndroidManifest.xml:

[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]

Schemat z poprzedniego przykładu to exampleapp:// (zauważ również kategoria BROWSABLE)

Następnie, w polu danych, możesz określić host i path:

<data android:scheme="examplescheme"
android:host="example"
/>

Aby uzyskać do niego dostęp z sieci, można ustawić link jak:

<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>

Aby znaleźć kod, który będzie wykonywany w aplikacji, przejdź do aktywności wywoływanej przez deeplink i poszukaj funkcji onNewIntent.

Dowiedz się, jak wywoływać deep linki bez użycia stron HTML.

AIDL - Android Interface Definition Language

Android Interface Definition Language (AIDL) jest zaprojektowany w celu ułatwienia komunikacji między klientem a usługą w aplikacjach Android poprzez komunikację międzyprocesową (IPC). Ponieważ bezpośredni dostęp do pamięci innego procesu nie jest dozwolony w Androidzie, AIDL upraszcza ten proces, marshalling obiektów do formatu zrozumiałego dla systemu operacyjnego, co ułatwia komunikację między różnymi procesami.

Kluczowe pojęcia

  • Usługi powiązane: Te usługi wykorzystują AIDL do IPC, umożliwiając aktywnościom lub komponentom powiązanie z usługą, składanie żądań i otrzymywanie odpowiedzi. Metoda onBind w klasie usługi jest kluczowa dla inicjowania interakcji, co czyni ją istotnym obszarem przeglądu bezpieczeństwa w poszukiwaniu luk.

  • Messenger: Działając jako usługa powiązana, Messenger ułatwia IPC z naciskiem na przetwarzanie danych poprzez metodę onBind. Ważne jest, aby dokładnie sprawdzić tę metodę pod kątem niebezpiecznego przetwarzania danych lub wykonywania wrażliwych funkcji.

  • Binder: Chociaż bezpośrednie użycie klasy Binder jest mniej powszechne z powodu abstrakcji AIDL, warto zrozumieć, że Binder działa jako sterownik na poziomie jądra, ułatwiając transfer danych między przestrzeniami pamięci różnych procesów. Dla dalszego zrozumienia dostępny jest zasób pod adresem https://www.youtube.com/watch?v=O-UHvFjxwZ8.

Komponenty

Należą do nich: Aktywności, Usługi, Odbiorniki Rozgłoszeniowe i Dostawcy.

Aktywność uruchamiająca i inne aktywności

W aplikacjach Android aktywności są jak ekrany, pokazujące różne części interfejsu użytkownika aplikacji. Aplikacja może mieć wiele aktywności, z których każda prezentuje unikalny ekran dla użytkownika.

Aktywność uruchamiająca jest głównym wejściem do aplikacji, uruchamianym po naciśnięciu ikony aplikacji. Jest zdefiniowana w pliku manifestu aplikacji z określonymi intencjami MAIN i LAUNCHER:

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Nie wszystkie aplikacje potrzebują aktywności uruchamiającej, szczególnie te bez interfejsu użytkownika, takie jak usługi w tle.

Aktywności mogą być udostępniane innym aplikacjom lub procesom poprzez oznaczenie ich jako "exported" w manifeście. To ustawienie pozwala innym aplikacjom na uruchomienie tej aktywności:

<service android:name=".ExampleExportedService" android:exported="true"/>

Jednak dostęp do aktywności z innej aplikacji nie zawsze stanowi zagrożenie dla bezpieczeństwa. Obawy pojawiają się, jeśli wrażliwe dane są udostępniane niewłaściwie, co może prowadzić do wycieków informacji.

Cykl życia aktywności zaczyna się od metody onCreate, która ustawia interfejs użytkownika i przygotowuje aktywność do interakcji z użytkownikiem.

Podklasa Aplikacji

W rozwoju Androida aplikacja ma możliwość stworzenia podklasy klasy Application, chociaż nie jest to obowiązkowe. Gdy taka podklasa jest zdefiniowana, staje się pierwszą klasą, która jest instancjonowana w aplikacji. Metoda attachBaseContext, jeśli jest zaimplementowana w tej podklasie, jest wykonywana przed metodą onCreate. Ta konfiguracja pozwala na wczesną inicjalizację przed rozpoczęciem działania reszty aplikacji.

public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}

@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}

Usługi

Usługi to operacje w tle, które mogą wykonywać zadania bez interfejsu użytkownika. Te zadania mogą kontynuować działanie nawet wtedy, gdy użytkownicy przełączają się na różne aplikacje, co sprawia, że usługi są kluczowe dla długoterminowych operacji.

Usługi są wszechstronne; mogą być inicjowane na różne sposoby, przy czym Intents są główną metodą ich uruchamiania jako punkt wejścia aplikacji. Gdy usługa jest uruchamiana za pomocą metody startService, jej metoda onStart zaczyna działać i działa aż do momentu, gdy metoda stopService zostanie wywołana. Alternatywnie, jeśli rola usługi zależy od aktywnego połączenia z klientem, używana jest metoda bindService do powiązania klienta z usługą, angażując metodę onBind do przesyłania danych.

Ciekawym zastosowaniem usług jest odtwarzanie muzyki w tle lub pobieranie danych z sieci bez zakłócania interakcji użytkownika z aplikacją. Ponadto, usługi mogą być udostępniane innym procesom na tym samym urządzeniu poprzez eksportowanie. Nie jest to domyślne zachowanie i wymaga wyraźnej konfiguracji w pliku Android Manifest:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receivers

Broadcast receivers działają jako słuchacze w systemie wiadomości, umożliwiając wielu aplikacjom reagowanie na te same wiadomości z systemu. Aplikacja może zarejestrować odbiornik na dwa główne sposoby: poprzez Manifest aplikacji lub dynamicznie w kodzie aplikacji za pomocą API registerReceiver. W Manifeście, transmisje są filtrowane za pomocą uprawnień, podczas gdy dynamicznie zarejestrowane odbiorniki mogą również określać uprawnienia podczas rejestracji.

Filtry intencji są kluczowe w obu metodach rejestracji, określając, które transmisje uruchamiają odbiornik. Gdy odpowiednia transmisja zostanie wysłana, wywoływana jest metoda onReceive odbiornika, co umożliwia aplikacji odpowiednią reakcję, na przykład dostosowanie zachowania w odpowiedzi na alert o niskim poziomie baterii.

Transmisje mogą być asynchroniczne, docierając do wszystkich odbiorników bez kolejności, lub synchronizowane, gdzie odbiorniki otrzymują transmisję na podstawie ustalonych priorytetów. Ważne jest jednak, aby zauważyć potencjalne ryzyko bezpieczeństwa, ponieważ każda aplikacja może nadać sobie priorytet, aby przechwycić transmisję.

Aby zrozumieć funkcjonalność odbiornika, należy poszukać metody onReceive w jego klasie. Kod tej metody może manipulować otrzymaną Intencją, co podkreśla potrzebę walidacji danych przez odbiorniki, szczególnie w Ordered Broadcasts, które mogą modyfikować lub odrzucać Intencję.

Content Provider

Content Providers są niezbędne do dzielenia się danymi strukturalnymi między aplikacjami, podkreślając znaczenie wdrażania uprawnień w celu zapewnienia bezpieczeństwa danych. Umożliwiają aplikacjom dostęp do danych z różnych źródeł, w tym baz danych, systemów plików lub internetu. Specyficzne uprawnienia, takie jak readPermission i writePermission, są kluczowe dla kontrolowania dostępu. Dodatkowo, tymczasowy dostęp może być przyznany poprzez ustawienia grantUriPermission w manifeście aplikacji, wykorzystując atrybuty takie jak path, pathPrefix i pathPattern do szczegółowej kontroli dostępu.

Walidacja danych jest kluczowa, aby zapobiec lukom w zabezpieczeniach, takim jak SQL injection. Content Providers wspierają podstawowe operacje: insert(), update(), delete(), i query(), ułatwiając manipulację danymi i ich udostępnianie między aplikacjami.

FileProvider, wyspecjalizowany Content Provider, koncentruje się na bezpiecznym udostępnianiu plików. Jest definiowany w manifeście aplikacji z określonymi atrybutami do kontrolowania dostępu do folderów, oznaczonymi przez android:exported i android:resource wskazującymi na konfiguracje folderów. Należy zachować ostrożność przy udostępnianiu katalogów, aby uniknąć przypadkowego ujawnienia wrażliwych danych.

Przykład deklaracji manifestu dla FileProvider:

<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>

I przykład określania folderów współdzielonych w filepaths.xml:

<paths>
<files-path path="images/" name="myimages" />
</paths>

For further information check:

WebViews

WebViews są jak mini przeglądarki internetowe wewnątrz aplikacji Android, pobierające treści z internetu lub z lokalnych plików. Stają w obliczu podobnych ryzyk jak zwykłe przeglądarki, jednak istnieją sposoby na zmniejszenie tych ryzyk poprzez konkretne ustawienia.

Android oferuje dwa główne typy WebView:

  • WebViewClient jest świetny do podstawowego HTML, ale nie obsługuje funkcji alert JavaScript, co wpływa na to, jak można testować ataki XSS.

  • WebChromeClient działa bardziej jak pełne doświadczenie przeglądarki Chrome.

Kluczowym punktem jest to, że przeglądarki WebView nie dzielą ciasteczek z główną przeglądarką urządzenia.

Do ładowania treści dostępne są metody takie jak loadUrl, loadData, i loadDataWithBaseURL. Ważne jest, aby upewnić się, że te adresy URL lub pliki są bezpieczne do użycia. Ustawienia bezpieczeństwa można zarządzać za pomocą klasy WebSettings. Na przykład, wyłączenie JavaScript za pomocą setJavaScriptEnabled(false) może zapobiec atakom XSS.

JavaScript "Bridge" pozwala obiektom Java na interakcję z JavaScript, wymagając, aby metody były oznaczone jako @JavascriptInterface dla bezpieczeństwa od Androida 4.2 wzwyż.

Zezwolenie na dostęp do treści (setAllowContentAccess(true)) pozwala WebView na dostęp do Content Providers, co może stanowić ryzyko, chyba że adresy URL treści są zweryfikowane jako bezpieczne.

Aby kontrolować dostęp do plików:

  • Wyłączenie dostępu do plików (setAllowFileAccess(false)) ogranicza dostęp do systemu plików, z wyjątkami dla niektórych zasobów, zapewniając, że są one używane tylko do treści, które nie są wrażliwe.

Other App Components and Mobile Device Management

Digital Signing of Applications

  • Podpis cyfrowy jest koniecznością dla aplikacji Android, zapewniając, że są autentycznie napisane przed instalacją. Proces ten wykorzystuje certyfikat do identyfikacji aplikacji i musi być zweryfikowany przez menedżera pakietów urządzenia podczas instalacji. Aplikacje mogą być samopodpisane lub certyfikowane przez zewnętrzne CA, chroniąc przed nieautoryzowanym dostępem i zapewniając, że aplikacja pozostaje nienaruszona podczas dostarczania do urządzenia.

App Verification for Enhanced Security

  • Począwszy od Androida 4.2, funkcja zwana Weryfikacja aplikacji pozwala użytkownikom na sprawdzenie aplikacji pod kątem bezpieczeństwa przed instalacją. Ten proces weryfikacji może ostrzegać użytkowników przed potencjalnie szkodliwymi aplikacjami, a nawet zapobiegać instalacji szczególnie złośliwych, zwiększając bezpieczeństwo użytkowników.

Mobile Device Management (MDM)

  • Rozwiązania MDM zapewniają nadzór i bezpieczeństwo dla urządzeń mobilnych poprzez API administracji urządzeniami. Wymagają one zainstalowania aplikacji Android, aby skutecznie zarządzać i zabezpieczać urządzenia mobilne. Kluczowe funkcje obejmują egzekwowanie polityk haseł, wymuszanie szyfrowania pamięci oraz zezwalanie na zdalne usuwanie danych, zapewniając kompleksową kontrolę i bezpieczeństwo nad urządzeniami mobilnymi.

// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);

if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}

Try Hard Security Group

Wsparcie HackTricks

Last updated