Sicherheits-Checkliste

Android verfügt über integrierte Sicherheitsfunktionen, die die Häufigkeit und Auswirkungen von Sicherheitsproblemen in Apps erheblich reduzieren. Das System ist so konzipiert, dass Sie Ihre Apps in der Regel mit den Standardberechtigungen für System und Dateien erstellen können und schwierige Entscheidungen zur Sicherheit vermieden werden.

Die folgenden wichtigen Sicherheitsfunktionen helfen Ihnen, sichere Apps zu entwickeln:

  • Die Android-App-Sandbox, die Ihre App-Daten und die Codeausführung von anderen Apps isoliert.
  • Ein Anwendungsframework mit robusten Implementierungen gängiger Sicherheitsfunktionen wie Kryptografie, Berechtigungen und sichere Interprozesskommunikation (IPC).
  • Technologien wie Address Space Layout Randomization (ASLR), No-Execute (NX), ProPolice, safe_iop, OpenBSD dlmalloc und calloc sowie Linux mmap_min_addr zur Minimierung von Risiken, die mit häufigen Fehlern bei der Speicherverwaltung verbunden sind.
  • Vom Nutzer erteilte Berechtigungen, um den Zugriff auf Systemfunktionen und Nutzerdaten einzuschränken.
  • Anwendungsdefinierte Berechtigungen zur Steuerung von Anwendungsdaten auf App-Basis.

Es ist wichtig, dass Sie sich mit den Best Practices für die Android-Sicherheit auf dieser Seite vertraut machen. Wenn Sie diese Praktiken als allgemeine Programmiergewohnheiten befolgen, können Sie vermeiden, dass Sie versehentlich Sicherheitsprobleme einführen, die sich negativ auf Ihre Nutzer auswirken.

Authentifizierung

Die Authentifizierung ist eine Voraussetzung für viele wichtige Sicherheitsvorgänge. Um den Zugriff auf geschützte Assets wie Nutzerdaten, App-Funktionen und andere Ressourcen zu steuern, müssen Sie Ihrer Android-App eine Authentifizierung hinzufügen.

Sie können die Authentifizierung für Ihre Nutzer verbessern, indem Sie Ihre App in den Credential Manager einbinden. Credential Manager ist eine Android Jetpack-Bibliothek, die die API-Unterstützung für die meisten wichtigen Authentifizierungsmethoden vereinheitlicht, darunter Passkeys, Passwörter und Lösungen für die föderierte Anmeldung wie Über Google anmelden.

Um die Sicherheit Ihrer App weiter zu erhöhen, sollten Sie biometrische Authentifizierungsmethoden wie Fingerabdruck- oder Gesichtserkennung hinzufügen. Apps für Finanzdienstleistungen, das Gesundheitswesen oder die Identitätsverwaltung sind gute Kandidaten für die biometrische Authentifizierung.

Das Autofill-Framework von Android kann die Registrierung und Anmeldung vereinfachen und so Fehler und Frustrationen bei Nutzern reduzieren. Autofill ist in Passwortmanager integriert. Nutzer können so komplexe, zufällig generierte Passwörter auswählen, die einfach und sicher gespeichert und abgerufen werden können.

App-Integrität

Mit der Play Integrity API können Sie prüfen, ob Interaktionen und Serveranfragen von Ihrem echten App-Binärprogramm stammen, das auf einem echten Android-Gerät ausgeführt wird. Wenn potenziell riskante und betrügerische Interaktionen erkannt werden, z. B. von manipulierten App-Versionen und nicht vertrauenswürdigen Umgebungen, kann der Backend-Server Ihrer App mit geeigneten Aktionen reagieren, um Angriffe zu verhindern und Missbrauch zu reduzieren.

Datenspeicher

Die häufigste Sicherheitsbedenken bei einer Anwendung auf Android ist, ob die Daten, die Sie auf dem Gerät speichern, für andere Apps zugänglich sind. Es gibt drei grundlegende Möglichkeiten, Daten auf dem Gerät zu speichern:

  • Interner Speicher
  • Externer Speicher
  • Contentanbieter

In den folgenden Abschnitten werden die Sicherheitsrisiken beschrieben, die mit den einzelnen Ansätzen verbunden sind.

Interner Speicher

Standardmäßig sind Dateien, die Sie im internen Speicher erstellen, nur für Ihre App zugänglich. Android implementiert diesen Schutz, der für die meisten Anwendungen ausreichend ist.

Vermeiden Sie die eingestellten Modi MODE_WORLD_WRITEABLE und MODE_WORLD_READABLE für IPC-Dateien. Sie bieten keine Möglichkeit, den Datenzugriff auf bestimmte Anwendungen zu beschränken, und keine Kontrolle über das Datenformat. Wenn Sie Ihre Daten für andere App-Prozesse freigeben möchten, sollten Sie stattdessen einen Contentanbieter verwenden. Dieser bietet anderen Apps Lese- und Schreibberechtigungen und kann Berechtigungen dynamisch für jeden Einzelfall erteilen.

Externer Speicher

Dateien, die auf externem Speicher wie SD-Karten erstellt werden, sind global lesbar und beschreibbar. Da externer Speicher vom Nutzer entfernt und von jeder Anwendung geändert werden kann, sollten Sie nur nicht vertrauliche Informationen im externen Speicher ablegen.

Führen Sie eine Eingabevalidierung durch, wenn Sie Daten aus externem Speicher verarbeiten, so wie Sie es bei Daten aus einer nicht vertrauenswürdigen Quelle tun würden. Speichern Sie keine ausführbaren Dateien oder Klassendateien auf externen Speichermedien, bevor sie dynamisch geladen werden. Wenn Ihre App ausführbare Dateien aus dem externen Speicher abruft, müssen Sie dafür sorgen, dass die Dateien vor dem dynamischen Laden signiert und kryptografisch überprüft werden.

Contentanbieter

Contentanbieter bieten einen strukturierten Speichermechanismus, der auf Ihre eigene Anwendung beschränkt oder exportiert werden kann, um den Zugriff durch andere Anwendungen zu ermöglichen. Wenn Sie anderen Anwendungen keinen Zugriff auf Ihre ContentProvider gewähren möchten, markieren Sie sie im Anwendungsmanifest als android:exported=false. Andernfalls legen Sie das Attribut android:exported auf true fest, damit andere Apps auf die gespeicherten Daten zugreifen können.

Wenn Sie eine ContentProvider erstellen, die für die Verwendung durch andere Anwendungen exportiert wird, können Sie eine einzelne Berechtigung für Lese- und Schreibvorgänge oder separate Berechtigungen für Lese- und Schreibvorgänge angeben. Beschränken Sie die Berechtigungen auf die, die für die jeweilige Aufgabe erforderlich sind. Es ist in der Regel einfacher, später Berechtigungen hinzuzufügen, um neue Funktionen zu ermöglichen, als Berechtigungen zu entfernen und damit bestehende Nutzer zu beeinträchtigen.

Wenn Sie einen Contentanbieter verwenden, um Daten nur zwischen Ihren eigenen Apps zu teilen, empfehlen wir, das Attribut android:protectionLevel auf den Schutz signature festzulegen. Für Signaturberechtigungen ist keine Nutzerbestätigung erforderlich. Sie bieten also eine bessere Nutzerfreundlichkeit und einen kontrollierteren Zugriff auf die Daten des Contentanbieters, wenn die Apps, die auf die Daten zugreifen, mit demselben Schlüssel signiert sind.

Inhalteanbieter können auch einen detaillierteren Zugriff ermöglichen, indem sie das Attribut android:grantUriPermissions deklarieren und die Flags FLAG_GRANT_READ_URI_PERMISSION und FLAG_GRANT_WRITE_URI_PERMISSION im Intent-Objekt verwenden, das die Komponente aktiviert. Der Umfang dieser Berechtigungen kann durch das Element <grant-uri-permission> weiter eingeschränkt werden.

Verwenden Sie beim Zugriff auf einen Contentanbieter parametrisierte Abfragemethoden wie query, update und delete(), um potenzielle SQL-Injection-Angriffe aus nicht vertrauenswürdigen Quellen zu vermeiden. Die Verwendung parametrisierter Methoden reicht nicht aus, wenn das selection-Argument durch Verketten von Nutzerdaten erstellt wird, bevor es an die Methode gesendet wird.

Verlassen Sie sich nicht darauf, dass die Schreibberechtigung für Sicherheit sorgt. Mit der Schreibberechtigung sind SQL-Anweisungen möglich, mit denen einige Daten mithilfe von WHERE-Klauseln im Creative bestätigt und die Ergebnisse geparst werden können. Ein Angreifer könnte beispielsweise prüfen, ob eine bestimmte Telefonnummer in einem Anrufprotokoll vorhanden ist, indem er eine Zeile nur ändert, wenn diese Telefonnummer bereits vorhanden ist. Wenn die Daten des Inhaltsanbieters eine vorhersehbare Struktur haben, kann die Schreibberechtigung sowohl Lese- als auch Schreibzugriff gewähren.

Berechtigungen

Da Android Anwendungen voneinander isoliert, müssen Anwendungen Ressourcen und Daten explizit freigeben. Dazu deklarieren sie die Berechtigungen, die sie für zusätzliche Funktionen benötigen, die nicht von der einfachen Sandbox bereitgestellt werden, einschließlich des Zugriffs auf Gerätefunktionen wie die Kamera.

Berechtigungsanfragen

Minimieren Sie die Anzahl der Berechtigungen, die von Ihrer App angefordert werden. Wenn Sie den Zugriff auf vertrauliche Berechtigungen einschränken, verringert sich das Risiko eines unbeabsichtigten Missbrauchs dieser Berechtigungen. Außerdem wird die Akzeptanz bei Nutzern verbessert und Ihre App ist weniger anfällig für Angriffe. Im Allgemeinen gilt: Wenn eine Berechtigung nicht für die Funktion Ihrer App erforderlich ist, sollten Sie sie nicht anfordern. Weitere Informationen finden Sie in der Anleitung zum Bewerten, ob Ihre App Berechtigungen deklarieren muss.

Gestalten Sie Ihre Anwendung nach Möglichkeit so, dass keine Berechtigungen erforderlich sind. Anstatt beispielsweise Zugriff auf Geräteinformationen anzufordern, um eine eindeutige Kennung zu erstellen, sollten Sie eine UUID für Ihre App erstellen. (Weitere Informationen im Abschnitt über Nutzerdaten). Alternativ können Sie Daten im internen Speicher speichern, anstatt externen Speicher zu verwenden (was eine Berechtigung erfordert).

Neben dem Anfordern von Berechtigungen kann Ihre Anwendung das Element <permission> verwenden, um sicherheitssensible IPC zu schützen, die für andere Anwendungen wie eine ContentProvider verfügbar gemacht wird. Im Allgemeinen empfehlen wir, nach Möglichkeit andere Zugriffskontrollen als vom Nutzer bestätigte Berechtigungen zu verwenden, da Berechtigungen für Nutzer verwirrend sein können. Verwenden Sie beispielsweise die Signaturschutzebene für Berechtigungen für die IPC-Kommunikation zwischen Anwendungen, die von einem einzelnen Entwickler bereitgestellt werden.

Geben Sie keine berechtigungsgeschützten Daten weiter. Dies tritt auf, wenn Ihre App Daten über IPC bereitstellt, die nur verfügbar sind, weil Ihre App die Berechtigung hat, auf diese Daten zuzugreifen. Die Clients der IPC-Schnittstelle Ihrer App haben möglicherweise nicht dieselbe Berechtigung für den Datenzugriff. Weitere Informationen zur Häufigkeit und den potenziellen Auswirkungen dieses Problems finden Sie im USENIX-Forschungsbericht Permission Re-Delegation: Attacks and Defenses.

Berechtigungsdefinitionen

Definieren Sie die kleinste Gruppe von Berechtigungen, die Ihren Sicherheitsanforderungen entspricht. Das Erstellen einer neuen Berechtigung ist für die meisten Anwendungen relativ ungewöhnlich, da die systemdefinierten Berechtigungen viele Situationen abdecken. Führen Sie gegebenenfalls Zugriffsprüfungen mit vorhandenen Berechtigungen durch.

Wenn Sie eine neue Berechtigung benötigen, sollten Sie prüfen, ob Sie Ihre Aufgabe mit einer Signaturschutzebene erledigen können. Signaturberechtigungen sind für den Nutzer transparent und ermöglichen den Zugriff nur durch Anwendungen, die vom selben Entwickler wie die Anwendung signiert wurden, die die Berechtigungsprüfung durchführt.

Wenn Sie weiterhin eine neue Berechtigung erstellen müssen, deklarieren Sie sie im App-Manifest mit dem Element <permission>. Apps, die die neue Berechtigung verwenden, können darauf verweisen, indem sie in ihren Manifestdateien ein <uses-permission>-Element hinzufügen. Sie können Berechtigungen auch dynamisch mit der Methode addPermission() hinzufügen.

Wenn Sie eine Berechtigung mit der Schutzstufe „dangerous“ erstellen, müssen Sie Folgendes beachten:

  • Die Berechtigung muss einen String enthalten, der dem Nutzer die erforderliche Sicherheitsentscheidung prägnant erläutert.
  • Der Berechtigungsstring muss in viele verschiedene Sprachen übersetzt werden.
  • Nutzer entscheiden sich möglicherweise gegen die Installation einer App, weil eine Berechtigung verwirrend ist oder als riskant wahrgenommen wird.
  • Apps können die Berechtigung anfordern, wenn der Ersteller der Berechtigung nicht installiert wurde.

Jede dieser Situationen stellt eine erhebliche nicht technische Herausforderung für Sie als Entwickler dar und verwirrt Ihre Nutzer. Aus diesem Grund raten wir von der Verwendung der Berechtigungsstufe „gefährlich“ ab.

Netzwerk

Netzwerktransaktionen sind von Natur aus sicherheitsrisikoreich, da dabei potenziell private Daten des Nutzers übertragen werden. Nutzer sind sich der Bedenken im Hinblick auf den Datenschutz bei Mobilgeräten immer bewusster, insbesondere wenn das Gerät Netzwerktransaktionen ausführt. Daher ist es sehr wichtig, dass Ihre App alle Best Practices einhält, um die Datensicherheit der Nutzer jederzeit zu gewährleisten.

IP-Netzwerk

Die Netzwerkfunktionen von Android unterscheiden sich nicht wesentlich von anderen Linux-Umgebungen. Wichtig ist, dass für sensible Daten geeignete Protokolle verwendet werden, z. B. HttpsURLConnection für sicheren Web-Traffic. Verwenden Sie HTTPS anstelle von HTTP, wenn HTTPS auf dem Server unterstützt wird, da Mobilgeräte häufig über ungesicherte Netzwerke wie öffentliche WLAN-Hotspots verbunden sind.

Die authentifizierte, verschlüsselte Kommunikation auf Socket-Ebene lässt sich mit der Klasse SSLSocket ganz einfach implementieren. Angesichts der Häufigkeit, mit der Android-Geräte über WLAN eine Verbindung zu ungesicherten WLANs herstellen, wird die Verwendung sicherer Netzwerke für alle Anwendungen, die über das Netzwerk kommunizieren, dringend empfohlen.

Einige Anwendungen verwenden localhost-Netzwerkports für die Verarbeitung sensibler IPC. Verwenden Sie diesen Ansatz nicht, da andere Anwendungen auf dem Gerät auf diese Schnittstellen zugreifen können. Verwenden Sie stattdessen einen Android-IPC-Mechanismus, bei dem die Authentifizierung möglich ist, z. B. mit einem Service. Die Bindung an die nicht spezifische IP-Adresse INADDR_ANY ist schlechter als die Verwendung von Loopback, da Ihre Anwendung dadurch Anfragen von jeder IP-Adresse empfangen kann.

Verlassen Sie sich nicht auf Daten, die über HTTP oder andere unsichere Protokolle heruntergeladen wurden. Dazu gehört die Validierung von Eingaben in WebView und aller Antworten auf Intents, die über HTTP ausgegeben werden.

Telefonie-Netzwerk

Das SMS-Protokoll (Short Message Service) wurde hauptsächlich für die Kommunikation zwischen Nutzern entwickelt und ist nicht gut für Apps geeignet, die Daten übertragen möchten. Aufgrund der Einschränkungen von SMS empfehlen wir, Firebase Cloud Messaging (FCM) und IP-Netzwerke zu verwenden, um Datenmeldungen von einem Webserver an Ihre App auf einem Nutzergerät zu senden.

SMS sind weder im Netzwerk noch auf dem Gerät verschlüsselt oder stark authentifiziert. Insbesondere sollte jeder SMS-Empfänger davon ausgehen, dass ein böswilliger Nutzer die SMS an Ihre Anwendung gesendet hat. Verlassen Sie sich bei der Ausführung vertraulicher Befehle nicht auf nicht authentifizierte SMS-Daten. Außerdem können SMS im Netzwerk manipuliert und/oder abgefangen werden. Auf dem Android-Gerät selbst werden SMS als Broadcast-Intents übertragen, sodass sie von anderen Anwendungen mit der Berechtigung READ_SMS gelesen oder erfasst werden können.

Eingabevalidierung

Unzureichende Eingabevalidierung ist eines der häufigsten Sicherheitsprobleme, die Anwendungen betreffen, unabhängig davon, auf welcher Plattform sie ausgeführt werden. Android bietet Gegenmaßnahmen auf Plattformebene, die die Anfälligkeit von Anwendungen für Probleme bei der Eingabevalidierung verringern. Wir empfehlen, diese Funktionen nach Möglichkeit zu nutzen. Außerdem empfehlen wir, typsichere Sprachen zu verwenden, um die Wahrscheinlichkeit von Problemen bei der Eingabevalidierung zu verringern.

Wenn Sie nativen Code verwenden, können alle Daten, die aus Dateien gelesen, über das Netzwerk empfangen oder von einem IPC empfangen werden, ein Sicherheitsproblem darstellen. Die häufigsten Probleme sind Pufferüberläufe, Use-After-Free-Fehler und Off-by-One-Fehler. Android bietet eine Reihe von Technologien wie ASLR und Data Execution Prevention (DEP), die die Ausnutzbarkeit dieser Fehler verringern, aber das zugrunde liegende Problem nicht lösen. Sie können diese Sicherheitslücken vermeiden, indem Sie sorgfältig mit Zeigern umgehen und Puffer verwalten.

Dynamische, stringbasierte Sprachen wie JavaScript und SQL sind aufgrund von Escapezeichen und Script-Injection ebenfalls anfällig für Probleme bei der Eingabevalidierung.

Wenn Sie Daten in Abfragen verwenden, die an eine SQL-Datenbank oder einen Content-Anbieter gesendet werden, kann SQL-Injection ein Problem sein. Die beste Verteidigung ist die Verwendung parametrisierter Abfragen, wie im Abschnitt zu Content-Providern beschrieben. Wenn Sie Berechtigungen auf Nur-Lese- oder Nur-Schreibzugriff beschränken, können Sie auch das Risiko von Schäden durch SQL-Injection verringern.

Wenn Sie die in diesem Abschnitt beschriebenen Sicherheitsfunktionen nicht verwenden können, achten Sie darauf, gut strukturierte Datenformate zu verwenden und zu prüfen, ob die Daten dem erwarteten Format entsprechen. Das Blockieren bestimmter Zeichen oder das Ersetzen von Zeichen kann eine effektive Strategie sein. In der Praxis sind diese Techniken jedoch fehleranfällig. Wir empfehlen, sie nach Möglichkeit zu vermeiden.

Nutzerdaten

Die Datensicherheit von Nutzerdaten lässt sich am besten dadurch erhöhen, dass Sie so selten wie möglich APIs verwenden, die auf vertrauliche und personenbezogene Informationen zugreifen. Wenn Sie Zugriff auf Nutzerdaten haben, sollten Sie sie nicht speichern oder übertragen, wenn Sie darauf verzichten können. Kann deine Anwendungslogik so implementiert werden, dass die Daten dabei als Hash-Werte oder in einem nicht umkehrbaren Format vorliegen? Wenn Sie z. B. den Hash-Wert einer E-Mail-Adresse als primären Schlüssel verwenden, muss die Adresse nicht übertragen oder gespeichert werden. Dadurch sinkt das Risiko, dass Daten ungewollt offengelegt werden. Außerdem wird es für Angreifer schwerer, deine App zu missbrauchen.

Authentifizieren Sie Nutzer immer, wenn Zugriff auf private Daten erforderlich ist, und verwenden Sie moderne Authentifizierungsmethoden wie Passkeys und Credential Manager. Wenn Ihre App auf personenbezogene Daten zugreifen muss, denken Sie daran, dass Sie in einigen Gerichtsbarkeiten möglicherweise eine Datenschutzerklärung bereitstellen müssen, in der Sie die Verwendung und Speicherung dieser Daten erläutern. Halten Sie sich an die Best Practice für Sicherheit, den Zugriff auf Nutzerdaten zu minimieren, um die Compliance zu vereinfachen.

Überlegen Sie auch, ob Ihre Anwendung versehentlich personenbezogene Daten an andere Parteien weitergeben könnte, z. B. an Drittanbieterkomponenten für Werbung oder an von Ihrer Anwendung verwendete Drittanbieterdienste. Wenn Sie nicht wissen, warum eine Komponente oder ein Dienst personenbezogene Daten benötigt, geben Sie diese nicht an. Im Allgemeinen verringert sich das Potenzial für Probleme in diesem Bereich, wenn Sie den Zugriff Ihrer Anwendung auf personenbezogene Daten einschränken.

Wenn Ihre App Zugriff auf sensible Daten benötigt, prüfen Sie, ob Sie diese an einen Server übertragen müssen oder ob Sie den Vorgang auf dem Client ausführen können. Erwägen Sie, Code mit sensiblen Daten auf dem Client auszuführen, um die Übertragung von Nutzerdaten zu vermeiden. Achten Sie außerdem darauf, dass Sie Nutzerdaten nicht versehentlich für andere Anwendungen auf dem Gerät freigeben, indem Sie IPC-Mechanismen mit zu vielen Berechtigungen, weltweit beschreibbare Dateien oder Netzwerksockets verwenden. Eine zu permissive IPC ist ein Sonderfall des Leckens von durch Berechtigungen geschützten Daten, das im Abschnitt Berechtigungsanfragen behandelt wird.

Wenn eine Globally Unique Identifier (GUID) erforderlich ist, erstellen Sie eine große, eindeutige Zahl und speichern Sie sie. Verwenden Sie keine Telefonkennungen wie die Telefonnummer oder IMEI, die mit personenbezogenen Daten verknüpft sein können. Dieses Thema wird auf der Seite Best Practices für eindeutige Kennungen ausführlicher behandelt.

Seien Sie vorsichtig, wenn Sie in On-Device-Logs schreiben. Unter Android sind Logs eine gemeinsam genutzte Ressource und für Anwendungen mit der Berechtigung READ_LOGS verfügbar. Auch wenn die Daten des Telefonprotokolls temporär sind und beim Neustart gelöscht werden, kann eine unangemessene Protokollierung von Nutzerinformationen dazu führen, dass Nutzerdaten versehentlich an andere Anwendungen weitergegeben werden. Neben dem Verzicht auf die Protokollierung personenbezogener Daten sollten Sie die Protokollierung in Produktions-Apps einschränken. Verwenden Sie dazu Debug-Flags und benutzerdefinierte Log-Klassen mit einfach konfigurierbaren Logging-Ebenen.

WebView

Da WebView Webinhalte verwendet, die HTML und JavaScript enthalten können, kann eine unsachgemäße Verwendung zu häufigen Websicherheitsproblemen wie Cross-Site-Scripting (JavaScript-Injection) führen. Android bietet eine Reihe von Mechanismen, um den Umfang dieser potenziellen Probleme zu verringern, indem die Möglichkeiten von WebView auf die Mindestfunktionen beschränkt werden, die für Ihre Anwendung erforderlich sind.

Wenn in Ihrer Anwendung JavaScript nicht direkt in einem WebView verwendet wird, rufen Sie setJavaScriptEnabled nicht auf. In einigen Beispielcodes wird diese Methode verwendet. Wenn Sie Beispielcode, in dem sie verwendet wird, für eine Produktionsanwendung wiederverwenden, entfernen Sie diesen Methodenaufruf, falls er nicht erforderlich ist. Standardmäßig führt WebView keinen JavaScript-Code aus, sodass Cross-Site-Scripting nicht möglich ist.

Verwenden Sie addJavaScriptInterface() mit besonderer Vorsicht, da JavaScript damit Vorgänge aufrufen kann, die normalerweise Android-Anwendungen vorbehalten sind. Wenn Sie es verwenden, machen Sie addJavaScriptInterface() nur für Webseiten verfügbar, von denen alle Eingaben vertrauenswürdig sind. Wenn nicht vertrauenswürdige Eingaben zulässig sind, kann nicht vertrauenswürdiges JavaScript möglicherweise Android-Methoden in Ihrer App aufrufen. Im Allgemeinen empfehlen wir, addJavaScriptInterface() nur für JavaScript verfügbar zu machen, das im APK Ihrer Anwendung enthalten ist.

Wenn Ihre Anwendung mit einem WebView auf sensible Daten zugreift, sollten Sie die Methode clearCache() verwenden, um alle lokal gespeicherten Dateien zu löschen. Sie können auch serverseitige Header wie no-store verwenden, um anzugeben, dass eine Anwendung bestimmte Inhalte nicht im Cache speichern soll.

Auf Geräten mit Plattformen, die älter als Android 4.4 (API-Level 19) sind, wird eine Version von webkit verwendet, die eine Reihe von Sicherheitsproblemen aufweist. Wenn Ihre App auf diesen Geräten ausgeführt wird, muss sie als Workaround bestätigen, dass in WebView-Objekten nur vertrauenswürdige Inhalte angezeigt werden. Damit Ihre App nicht potenziellen Sicherheitslücken in SSL ausgesetzt ist, verwenden Sie das aktualisierbare Sicherheitsobjekt Provider, wie unter Sicherheitsanbieter zum Schutz vor SSL-Exploits aktualisieren beschrieben. Wenn Ihre Anwendung Inhalte aus dem offenen Web rendern muss, sollten Sie einen eigenen Renderer bereitstellen, damit Sie ihn mit den neuesten Sicherheitspatches auf dem neuesten Stand halten können.

Anmeldedatenanfragen

Anmeldedatenanfragen sind ein Angriffsvektor. Hier sind einige Tipps, wie Sie Anfragen für Anmeldedaten in Ihren Android-Apps sicherer gestalten können.

Freigabe von Anmeldedaten minimieren

  • Vermeiden Sie unnötige Anmeldedatenanfragen. Um Phishing-Angriffe auffälliger und weniger wahrscheinlich zu machen, sollten Sie Nutzeranmeldedaten so selten wie möglich abfragen. Verwenden Sie stattdessen ein Autorisierungstoken und aktualisieren Sie es. Fordern Sie nur die Mindestmenge an Anmeldedaten an, die für die Authentifizierung und Autorisierung erforderlich ist.
  • Anmeldedaten sicher speichern Mit dem Credential Manager können Sie die passwortlose Authentifizierung mit Passkeys aktivieren oder die föderierte Anmeldung mit Schemas wie „Über Google anmelden“ implementieren. Wenn Sie die herkömmliche Passwortauthentifizierung verwenden müssen, speichern Sie keine Nutzer-IDs und Passwörter auf dem Gerät. Führen Sie stattdessen die anfängliche Authentifizierung mit dem vom Nutzer angegebenen Nutzernamen und Passwort durch und verwenden Sie dann ein kurzlebiges, dienstspezifisches Autorisierungstoken.
  • Berechtigungen einschränken: Fordern Sie keine umfassenden Berechtigungen für eine Aufgabe an, die nur einen eingeschränkten Umfang erfordert.
  • Zugriffstokens einschränken: Verwenden Sie Vorgänge und API-Aufrufe mit kurzlebigen Tokens.
  • Authentifizierungsraten begrenzen: Schnelle, aufeinanderfolgende Authentifizierungs- oder Autorisierungsanfragen können ein Zeichen für einen Brute-Force-Angriff sein. Beschränken Sie diese Raten auf eine angemessene Häufigkeit, damit die App weiterhin funktionsfähig und nutzerfreundlich ist.

Sichere Authentifizierung verwenden

  • Passkeys implementieren Aktivieren Sie Passkeys als sicherere und nutzerfreundlichere Alternative zu Passwörtern.
  • Biometrische Daten hinzufügen Bieten Sie die Möglichkeit, biometrische Authentifizierung wie Fingerabdruck- oder Gesichtserkennung für zusätzliche Sicherheit zu verwenden.
  • Föderierte Identitätsanbieter verwenden: Credential Manager unterstützt föderierte Authentifizierungsanbieter wie Über Google anmelden.
  • Kommunikation verschlüsseln: Verwenden Sie HTTPS und ähnliche Technologien, um die Daten zu schützen, die Ihre App über ein Netzwerk sendet.

Sichere Kontoverwaltung

  • Verbinden Sie sich mit Diensten, auf die mehrere Anwendungen zugreifen können, indem Sie AccountManager verwenden. Verwenden Sie die Klasse AccountManager, um einen cloudbasierten Dienst aufzurufen, und speichern Sie keine Passwörter auf dem Gerät.
  • Nachdem Sie mit AccountManager ein Account abgerufen haben, verwenden Sie CREATOR, bevor Sie Anmeldedaten übergeben, damit Sie nicht versehentlich Anmeldedaten an die falsche Anwendung übergeben.
  • Wenn Anmeldedaten nur von Anwendungen verwendet werden, die Sie erstellen, können Sie die Anwendung, die auf AccountManager zugreift, mit checkSignatures überprüfen. Wenn das Anmeldedaten nur von einer Anwendung verwendet werden, können Sie sie alternativ auch in KeyStore speichern.

Bleiben Sie wachsam

  • Code auf dem neuesten Stand halten: Aktualisieren Sie Ihren Quellcode, einschließlich aller Drittanbieterbibliotheken und ‑abhängigkeiten, um sich vor den neuesten Sicherheitslücken zu schützen.
  • Verdächtige Aktivitäten im Blick behalten: Suchen Sie nach potenziellem Missbrauch, z. B. nach Mustern von Autorisierungsmissbrauch.
  • Code prüfen Führen Sie regelmäßig Sicherheitschecks für Ihren Code durch, um nach potenziellen Problemen mit Anfragen für Anmeldedaten zu suchen.

Verwalten von API-Schlüsseln

API-Schlüssel sind ein wichtiger Bestandteil vieler Android-Apps. Sie ermöglichen den Zugriff auf externe Dienste und die Ausführung wichtiger Funktionen wie die Verbindung zu Kartendiensten, die Authentifizierung und Wetterdienste. Die Offenlegung dieser sensiblen Schlüssel kann jedoch schwerwiegende Folgen haben, darunter Datenpannen, unbefugter Zugriff und finanzielle Verluste. Um solche Szenarien zu vermeiden, sollten Entwickler während des gesamten Entwicklungsprozesses sichere Strategien für den Umgang mit API-Schlüsseln implementieren.

Um Dienste vor Missbrauch zu schützen, müssen API-Schlüssel sorgfältig geschützt werden. Um eine Verbindung zwischen der App und einem Dienst zu sichern, für den ein API-Schlüssel verwendet wird, müssen Sie den Zugriff auf die API sichern. Wenn Ihre App kompiliert wird und der Quellcode Ihrer App API-Schlüssel enthält, kann ein Angreifer die App dekompilieren und diese Ressourcen finden.

Dieser Abschnitt richtet sich an zwei Gruppen von Android-Entwicklern: an diejenigen, die mit Infrastrukturteams an ihrer Pipeline für Continuous Delivery arbeiten, und an diejenigen, die eigenständige Apps im Play Store bereitstellen. In diesem Abschnitt werden Best Practices für den Umgang mit API-Schlüsseln beschrieben, damit Ihre App sicher mit Diensten kommunizieren kann.

Generierung und Speicherung

Entwickler sollten die Speicherung von API-Schlüsseln als kritische Komponente des Datenschutzes und der Privatsphäre der Nutzer betrachten und einen mehrschichtigen Ansatz verwenden.

Sichere Schlüsselspeicherung

Für eine optimale Sicherheit bei der Schlüsselverwaltung sollten Sie den Android-Schlüsselspeicher verwenden und gespeicherte Schlüssel mit einem robusten Tool wie Tink Java verschlüsseln.

Ausschluss von der Versionsverwaltung

Sichern Sie API-Schlüssel niemals in Ihrem Quellcode-Repository. Wenn Sie API-Schlüssel in den Quellcode einfügen, besteht das Risiko, dass die Schlüssel in öffentlichen Repositories, freigegebenen Codebeispielen und versehentlich freigegebenen Dateien offengelegt werden. Verwenden Sie stattdessen Gradle-Plug-ins wie das secrets-gradle-plugin, um API-Schlüssel in Ihrem Projekt zu verwenden.

Umgebungsspezifische Schlüssel

Verwenden Sie nach Möglichkeit separate API-Schlüssel für Entwicklungs-, Test- und Produktionsumgebungen. Verwenden Sie umgebungsspezifische Schlüssel, um die einzelnen Umgebungen zu isolieren. So verringern Sie das Risiko, dass Produktionsdaten offengelegt werden, und können manipulierte Schlüssel deaktivieren, ohne Ihre Produktionsumgebung zu beeinträchtigen.

Nutzung und Zugriffssteuerung

Sichere API-Schlüssel sind unerlässlich, um Ihre API und Ihre Nutzer zu schützen. So bereiten Sie Ihre Schlüssel für optimale Sicherheit vor:

  • Eindeutige Schlüssel für jede App generieren: Verwenden Sie für jede App separate API-Schlüssel, um kompromittierte Zugriffe leichter zu identifizieren und zu isolieren.
  • IP-Einschränkungen implementieren: Beschränken Sie die Nutzung von API-Schlüsseln nach Möglichkeit auf bestimmte IP-Adressen oder ‑Bereiche.
  • Verwendung von Schlüsseln für mobile Apps einschränken: Sie können die Verwendung von API-Schlüsseln auf bestimmte mobile Apps beschränken, indem Sie sie mit dem Schlüssel bündeln oder App-Zertifikate verwenden.
  • Verdächtige Aktivitäten protokollieren und überwachen: Implementieren Sie Mechanismen zum Protokollieren und Überwachen der API-Nutzung, um verdächtige Aktivitäten zu erkennen und potenziellen Missbrauch zu verhindern.

Hinweis: Ihr Dienst sollte Funktionen zum Einschränken von Schlüsseln auf ein bestimmtes Paket oder eine bestimmte Plattform bieten. Die Google Maps API schränkt den Schlüsselzugriff beispielsweise nach Paketname und Signaturschlüssel ein.

OAuth 2.0 bietet ein Framework für die Autorisierung des Zugriffs auf Ressourcen. Es definiert Standards für die Interaktion zwischen Clients und Servern und ermöglicht eine sichere Autorisierung. Mit OAuth 2.0 können Sie die Verwendung von API-Schlüsseln auf bestimmte Clients beschränken und den Zugriffsbereich so definieren, dass jeder API-Schlüssel nur die für den jeweiligen Zweck erforderliche Mindestzugriffsebene hat.

Schlüsselrotation und ‑ablauf

Um das Risiko eines unbefugten Zugriffs durch unentdeckte API-Schwachstellen zu verringern, ist es wichtig, API-Schlüssel regelmäßig zu rotieren. Der ISO 27001-Standard definiert einen Compliance-Rahmen für die Häufigkeit der Schlüsselrotation. In den meisten Fällen ist ein Schlüsselrotationszeitraum zwischen 90 Tagen und 6 Monaten angemessen. Durch die Implementierung eines robusten Schlüsselverwaltungssystems können Sie diese Prozesse optimieren und die Effizienz Ihrer Anforderungen an die Schlüsselrotation und den Ablauf verbessern.

Allgemeine Best Practices

  • SSL/HTTPS verwenden: Verwenden Sie immer die HTTPS-Kommunikation, um Ihre API-Anfragen zu verschlüsseln.
  • Certificate Pinning: Um die Sicherheit zusätzlich zu erhöhen, können Sie Certificate Pinning implementieren, um zu prüfen, welche Zertifikate als gültig gelten.
  • Nutzereingaben validieren und bereinigen: Validieren und bereinigen Sie Nutzereingaben, um Einschleusungsangriffe zu verhindern, die API-Schlüssel offenlegen könnten.
  • Best Practices für die Sicherheit: Implementieren Sie allgemeine Best Practices für die Sicherheit in Ihrem Entwicklungsprozess, einschließlich sicherer Programmiertechniken, Code-Reviews und Scans auf Sicherheitslücken.
  • Auf dem Laufenden bleiben: Informieren Sie sich über die neuesten Sicherheitsrisiken und Best Practices für die Verwaltung von API-Schlüsseln.
  • SDKs auf dem neuesten Stand halten: Achten Sie darauf, dass Ihre SDKs und Bibliotheken auf die neueste Version aktualisiert sind.

Kryptografie

Android bietet nicht nur Datenisolation, Unterstützung für die vollständige Dateisystemverschlüsselung und sichere Kommunikationskanäle, sondern auch eine Vielzahl von Algorithmen zum Schutz von Daten mithilfe von Kryptografie.

Sie müssen wissen, welche JCA-Sicherheitsanbieter (Java Cryptography Architecture) Ihre Software verwendet. Verwenden Sie nach Möglichkeit die höchste Ebene der vorhandenen Framework-Implementierung, die Ihren Anwendungsfall unterstützt. Verwenden Sie gegebenenfalls die von Google bereitgestellten Anbieter in der von Google angegebenen Reihenfolge.

Wenn Sie eine Datei sicher von einem bekannten Netzwerkspeicherort abrufen müssen, ist möglicherweise eine einfache HTTPS-URI ausreichend, für die keine Kenntnisse der Kryptografie erforderlich sind. Wenn Sie einen sicheren Tunnel benötigen, sollten Sie HttpsURLConnection oder SSLSocket verwenden, anstatt ein eigenes Protokoll zu schreiben. Wenn Sie SSLSocket verwenden, beachten Sie, dass keine Hostname-Überprüfung erfolgt. Warnungen zur direkten Verwendung von SSLSocket

Wenn Sie feststellen, dass Sie ein eigenes Protokoll implementieren müssen, sollten Sie keine eigenen kryptografischen Algorithmen implementieren. Verwenden Sie vorhandene kryptografische Algorithmen wie die Implementierungen von AES und RSA, die in der Klasse Cipher bereitgestellt werden. Beachten Sie außerdem die folgenden Best Practices:

  • Verwenden Sie 256‑Bit-AES für kommerzielle Zwecke. (Falls nicht verfügbar, verwenden Sie AES mit 128 Bit.)
  • Verwenden Sie für die Elliptic Curve-Kryptografie (EC) entweder 224- oder 256-Bit-Schlüsselgrößen für öffentliche Schlüssel.
  • Wissen, wann die Blockmodi CBC, CTR oder GCM verwendet werden sollten.
  • Vermeiden Sie die Wiederverwendung von IV/Zähler im CTR-Modus. Sie müssen kryptografisch zufällig sein.
  • Wenn Sie die Verschlüsselung verwenden, implementieren Sie die Integrität mit dem CBC- oder CTR-Modus mit einer der folgenden Funktionen:
    • HMAC-SHA1
    • HMAC-SHA-256
    • HMAC-SHA-512
    • GCM-Modus

Verwenden Sie einen sicheren Zufallszahlengenerator, SecureRandom, um alle kryptografischen Schlüssel zu initialisieren, die von KeyGenerator generiert werden. Die Verwendung eines Schlüssels, der nicht mit einem sicheren Zufallszahlengenerator generiert wurde, schwächt die Stärke des Algorithmus erheblich und kann Offline-Angriffe ermöglichen.

Wenn Sie einen Schlüssel für die wiederholte Verwendung speichern müssen, verwenden Sie einen Mechanismus wie KeyStore, der die langfristige Speicherung und den Abruf von kryptografischen Schlüsseln ermöglicht.

Interprozesskommunikation

Einige Apps versuchen, IPC mit herkömmlichen Linux-Techniken wie Netzwerksockets und freigegebenen Dateien zu implementieren. Wir empfehlen jedoch stattdessen, Android-Systemfunktionen für die IPC zu verwenden, z. B. Intent, Binder oder Messenger mit einem Service und BroadcastReceiver. Mit den Android-IPC-Mechanismen können Sie die Identität der Anwendung überprüfen, die eine Verbindung zu Ihrem IPC herstellt, und für jeden IPC-Mechanismus eine Sicherheitsrichtlinie festlegen.

Viele Sicherheitselemente sind für alle IPC-Mechanismen gleich. Wenn Ihr IPC-Mechanismus nicht für die Verwendung durch andere Anwendungen vorgesehen ist, legen Sie das Attribut android:exported im Manifestelement der Komponente, z. B. für das Element <service>, auf false fest. Dies ist nützlich für Anwendungen, die aus mehreren Prozessen innerhalb derselben UID bestehen, oder wenn Sie erst spät in der Entwicklung entscheiden, dass Sie keine Funktionen als IPC verfügbar machen möchten, den Code aber nicht neu schreiben möchten.

Wenn Ihr IPC für andere Anwendungen zugänglich ist, können Sie eine Sicherheitsrichtlinie mit dem Element <permission> anwenden. Wenn die IPC zwischen Apps erfolgt, die Ihnen gehören und mit demselben Schlüssel signiert sind, verwenden Sie die Berechtigung signature-level im android:protectionLevel.

Intents

Für Aktivitäten und Broadcast-Empfänger sind Intents der bevorzugte Mechanismus für die asynchrone IPC unter Android. Je nach den Anforderungen Ihrer Anwendung können Sie sendBroadcast, sendOrderedBroadcast oder einen expliziten Intent für eine bestimmte Anwendungskomponente verwenden. Aus Sicherheitsgründen werden explizite Intents bevorzugt.

Geordnete Broadcasts können von einem Empfänger verarbeitet werden. Sie werden daher möglicherweise nicht an alle Anwendungen gesendet. Wenn Sie einen Intent senden, der an einen bestimmten Empfänger gesendet werden muss, müssen Sie einen expliziten Intent verwenden, in dem der Empfänger namentlich deklariert wird.

Absender eines Intents können prüfen, ob der Empfänger die Berechtigung hat, indem sie einen nicht leeren Wert für „permission“ im Methodenaufruf angeben. Nur Anwendungen mit dieser Berechtigung empfangen den Intent. Wenn Daten in einem Broadcast-Intent vertraulich sein könnten, sollten Sie eine Berechtigung anwenden, um sicherzustellen, dass sich schädliche Anwendungen nicht ohne entsprechende Berechtigungen für den Empfang dieser Nachrichten registrieren können. In diesen Fällen können Sie den Empfänger auch direkt aufrufen, anstatt eine Übertragung zu senden.

Dienste

Ein Service wird häufig verwendet, um anderen Anwendungen Funktionen zur Verfügung zu stellen. Jede Dienstklasse muss eine entsprechende <service>-Deklaration in ihrer Manifestdatei haben.

Standardmäßig werden Dienste nicht exportiert und können nicht von anderen Anwendungen aufgerufen werden. Wenn Sie der Dienstdeklaration jedoch Intent-Filter hinzufügen, wird sie standardmäßig exportiert. Am besten deklarieren Sie das Attribut android:exported explizit, damit es sich wie gewünscht verhält. Dienste können auch mit dem Attribut android:permission geschützt werden. Dazu müssen andere Anwendungen ein entsprechendes <uses-permission>-Element in ihrem eigenen Manifest deklarieren, um den Dienst starten, stoppen oder daran binden zu können.

Ein Dienst kann einzelne IPC-Aufrufe, die an ihn gerichtet sind, mit Berechtigungen schützen. Dazu wird checkCallingPermission() aufgerufen, bevor die Implementierung des Aufrufs ausgeführt wird. Wir empfehlen, die deklarativen Berechtigungen im Manifest zu verwenden, da sie weniger anfällig für Fehler sind.

Binder- und Messenger-Schnittstellen

Die Verwendung von Binder oder Messenger ist der bevorzugte Mechanismus für die RPC-basierte IPC unter Android. Sie bieten genau definierte Schnittstellen, die bei Bedarf eine gegenseitige Authentifizierung der Endpunkte ermöglichen.

Wir empfehlen, die App-Oberflächen so zu gestalten, dass keine oberflächenspezifischen Berechtigungsprüfungen erforderlich sind. Binder- und Messenger-Objekte werden nicht im Anwendungsmanifest deklariert. Daher können Sie keine deklarativen Berechtigungen direkt auf sie anwenden. Sie erben in der Regel Berechtigungen, die im Anwendungsmanifest für die Service oder Activity deklariert sind, in der sie implementiert werden. Wenn Sie eine Schnittstelle erstellen, für die eine Authentifizierung und/oder Zugriffssteuerung erforderlich ist, müssen Sie diese Steuerelemente explizit als Code in der Binder- oder Messenger-Schnittstelle hinzufügen.

Wenn Sie eine Schnittstelle bereitstellen, für die eine Zugriffssteuerung erforderlich ist, verwenden Sie checkCallingPermission(), um zu prüfen, ob der Aufrufer die erforderliche Berechtigung hat. Das ist besonders wichtig, bevor Sie im Namen des Anrufers auf einen Dienst zugreifen, da die Identität Ihrer Anwendung an andere Schnittstellen weitergegeben wird. Wenn Sie eine Schnittstelle aufrufen, die von einem Service bereitgestellt wird, kann der bindService()-Aufruf fehlschlagen, wenn Sie keine Berechtigung für den Zugriff auf den angegebenen Dienst haben. Wenn Sie einem externen Prozess die Interaktion mit Ihrer App erlauben müssen, er aber nicht die erforderlichen Berechtigungen dafür hat, können Sie die Methode clearCallingIdentity() verwenden. Bei dieser Methode wird der Aufruf der Benutzeroberfläche Ihrer App so ausgeführt, als ob Ihre App den Aufruf selbst ausführt und nicht der externe Anrufer. Sie können die Berechtigungen des Anrufers später mit der Methode restoreCallingIdentity() wiederherstellen.

Weitere Informationen zur IPC mit einem Dienst finden Sie unter Bound Services.

Übertragungsempfänger

Ein BroadcastReceiver verarbeitet asynchrone Anfragen, die von einem Intent initiiert werden.

Standardmäßig werden Receiver exportiert und können von jeder anderen Anwendung aufgerufen werden. Wenn Ihre BroadcastReceiver für die Verwendung durch andere Anwendungen vorgesehen ist, sollten Sie Sicherheitsberechtigungen für Empfänger mit dem Element <receiver> im Anwendungsmanifest anwenden. Dadurch wird verhindert, dass Anwendungen ohne die entsprechenden Berechtigungen einen Intent an BroadcastReceiver senden.

Sicherheit bei dynamisch geladenem Code

Wir raten dringend davon ab, Code von außerhalb des APK Ihrer Anwendung zu laden. Dadurch steigt die Wahrscheinlichkeit, dass die Anwendung durch Code-Injection oder Manipulation des Codes kompromittiert wird, erheblich. Außerdem wird die Versionsverwaltung und das Testen von Anwendungen komplexer. Es kann unmöglich sein, das Verhalten einer Anwendung zu überprüfen, weshalb die Verwendung in einigen Umgebungen verboten sein kann.

Wenn Ihre Anwendung Code dynamisch lädt, ist es am wichtigsten, dass der dynamisch geladene Code mit denselben Sicherheitsberechtigungen wie die Anwendungs-APK ausgeführt wird. Der Nutzer entscheidet sich aufgrund Ihrer Identität für die Installation Ihrer Anwendung und erwartet, dass Sie den gesamten in der Anwendung ausgeführten Code bereitstellen, einschließlich dynamisch geladenen Codes.

Viele Anwendungen versuchen, Code von unsicheren Orten zu laden, z. B. aus dem Netzwerk über unverschlüsselte Protokolle oder von Orten, die für alle Nutzer schreibbar sind, z. B. externer Speicher. An diesen Stellen könnte jemand im Netzwerk die Inhalte während der Übertragung oder eine andere Anwendung auf dem Gerät eines Nutzers die Inhalte auf dem Gerät ändern. Module, die direkt in Ihrem APK enthalten sind, können dagegen nicht von anderen Anwendungen geändert werden. Dies gilt unabhängig davon, ob der Code eine native Bibliothek oder eine Klasse ist, die mit DexClassLoader geladen wird.

Sicherheit in einer virtuellen Maschine

Dalvik ist die Laufzeit-VM von Android. Dalvik wurde speziell für Android entwickelt, aber viele der Bedenken hinsichtlich sicherem Code in anderen virtuellen Maschinen gelten auch für Android. Im Allgemeinen müssen Sie sich nicht um Sicherheitsprobleme im Zusammenhang mit der virtuellen Maschine kümmern. Ihre Anwendung wird in einer sicheren Sandbox-Umgebung ausgeführt, sodass andere Prozesse im System nicht auf Ihren Code oder Ihre privaten Daten zugreifen können.

Wenn Sie mehr über die Sicherheit virtueller Maschinen erfahren möchten, sollten Sie sich mit der vorhandenen Literatur zu diesem Thema vertraut machen. Zwei der beliebtesten Ressourcen sind:

In diesem Dokument werden Bereiche behandelt, die spezifisch für Android sind oder sich von anderen VM-Umgebungen unterscheiden. Für Entwickler, die bereits Erfahrung mit der VM-Programmierung in anderen Umgebungen haben, gibt es zwei allgemeine Probleme, die sich bei der Entwicklung von Apps für Android unterscheiden können:

  • Einige virtuelle Maschinen, z. B. die JVM oder die .NET-Laufzeit, fungieren als Sicherheitsgrenze und isolieren Code von den zugrunde liegenden Betriebssystemfunktionen. Unter Android ist die Dalvik VM keine Sicherheitsgrenze. Die Anwendungssandbox wird auf Betriebssystemebene implementiert, sodass Dalvik ohne Sicherheitsbeschränkungen mit nativem Code in derselben Anwendung interagieren kann.
  • Da der Speicherplatz auf Mobilgeräten begrenzt ist, möchten Entwickler häufig modulare Anwendungen erstellen und dynamisches Laden von Klassen verwenden. Berücksichtigen Sie dabei sowohl die Quelle, aus der Sie Ihre Anwendungslogik abrufen, als auch den Ort, an dem Sie sie lokal speichern. Verwenden Sie kein dynamisches Laden von Klassen aus nicht bestätigten Quellen wie ungesicherten Netzwerkquellen oder externem Speicher, da der Code möglicherweise so geändert wird, dass er schädliches Verhalten enthält.

Sicherheit in nativem Code

Im Allgemeinen empfehlen wir, für die App-Entwicklung das Android SDK anstelle von nativem Code mit dem Android NDK zu verwenden. Anwendungen, die mit nativem Code erstellt wurden, sind komplexer, weniger portabel und enthalten mit größerer Wahrscheinlichkeit häufige Speicherbeschädigungsfehler wie Pufferüberläufe.

Android basiert auf dem Linux-Kernel. Wenn Sie nativen Code verwenden, ist es besonders hilfreich, sich mit den Best Practices für die Sicherheit bei der Linux-Entwicklung vertraut zu machen. Linux-Sicherheitsverfahren fallen nicht in den Rahmen dieses Dokuments. Eine der beliebtesten Ressourcen ist jedoch Secure Programming HOWTO – Creating Secure Software.

Ein wichtiger Unterschied zwischen Android und den meisten Linux-Umgebungen ist die Anwendungssandbox. Unter Android werden alle Anwendungen in der Anwendungssandbox ausgeführt, auch solche, die mit nativem Code geschrieben wurden. Entwickler, die mit Linux vertraut sind, können sich das so vorstellen, dass jeder Anwendung eine eindeutige Nutzer-ID (User Identifier, UID) mit sehr eingeschränkten Berechtigungen zugewiesen wird. Dies wird in der Android-Sicherheitsübersicht ausführlicher behandelt. Sie sollten sich mit Anwendungsberechtigungen vertraut machen, auch wenn Sie nativen Code verwenden.