Interprozesskommunikation
Einige Apps versuchen, IPC mithilfe traditioneller Linux-Techniken wie Netzwerk-Sockets und gemeinsam genutzten Dateien zu implementieren. Wir empfehlen jedoch stattdessen die Verwendung von Android-Systemfunktionen für IPC wie Intent, Binder oder Messenger mit einem Dienst 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 Sicherheitsrichtlinien für jeden IPC-Mechanismus festlegen.
Viele der Sicherheitselemente werden von allen IPC-Mechanismen gemeinsam genutzt. Wenn Ihr IPC-Mechanismus nicht für die Verwendung durch andere Anwendungen vorgesehen ist, setzen Sie das Attribut „android:exported“ im Manifestelement der Komponente auf „false“, z. B. für das Element „<service>“. Dies ist nützlich für Anwendungen, die aus mehreren Prozessen innerhalb derselben UID bestehen, oder wenn Sie spät in der Entwicklung entscheiden, dass Sie die Funktionalität nicht wirklich als IPC verfügbar machen, aber den Code nicht neu schreiben möchten.
Wenn Ihr IPC für andere Anwendungen zugänglich ist, können Sie mithilfe des <permission>-Elements eine Sicherheitsrichtlinie anwenden. Wenn sich der IPC zwischen Apps befindet, die Ihnen gehören und mit demselben Schlüssel signiert sind, verwenden Sie eine Berechtigung auf Signaturebene im android:protectionLevel.
Absichten
Für Aktivitäten und Rundfunkempfänger sind Absichten der bevorzugte Mechanismus für asynchrones IPC auf Android. Abhängig von Ihren Anwendungsanforderungen können Sie sendBroadcast(), sendOrderedBroadcast() oder eine explizite Absicht für eine bestimmte Anwendungskomponente verwenden. Aus Sicherheitsgründen werden explizite Absichten bevorzugt.
Achtung: Wenn Sie eine Absicht zur Bindung an einen Dienst verwenden, verwenden Sie eine explizite Absicht, um die Sicherheit Ihrer App zu gewährleisten. Die Verwendung einer impliziten Absicht zum Starten eines Dienstes stellt ein Sicherheitsrisiko dar, da Sie nicht sicher sein können, welcher Dienst auf die Absicht reagiert, und der Benutzer nicht sehen kann, welcher Dienst gestartet wird. Ab Android 5.0 (API-Level 21) löst das System eine Ausnahme aus, wenn Sie bindService() mit einer impliziten Absicht aufrufen.
Beachten Sie, dass geordnete Broadcasts von einem Empfänger verbraucht werden können, sodass sie möglicherweise nicht an alle Anwendungen zugestellt werden. Wenn Sie eine Absicht senden, die an einen bestimmten Empfänger übermittelt werden muss, müssen Sie eine explizite Absicht verwenden, die den Empfänger namentlich angibt.
Absender einer Absicht können überprüfen, ob der Empfänger über die Berechtigung verfügt, indem sie beim Methodenaufruf eine Berechtigung ungleich Null angeben. Nur Anwendungen mit dieser Berechtigung erhalten die Absicht. Wenn Daten innerhalb einer Broadcast-Absicht vertraulich sein könnten, sollten Sie die Anwendung einer Berechtigung in Betracht ziehen, um sicherzustellen, dass sich bösartige Anwendungen nicht ohne entsprechende Berechtigungen für den Empfang dieser Nachrichten registrieren können. Unter diesen Umständen könnten Sie auch erwägen, den Empfänger direkt anzurufen, anstatt eine Übertragung auszulösen.
Hinweis: Absichtsfilter sind keine Sicherheitsfunktionen. Komponenten können mit expliziten Absichten aufgerufen werden und verfügen möglicherweise nicht über Daten, die dem Absichtsfilter entsprechen würden. Um zu bestätigen, dass es für den aufgerufenen Empfänger, Dienst oder die aufgerufene Aktivität richtig formatiert ist, führen Sie eine Eingabevalidierung in Ihrem Absichtsempfänger durch.
Dienstleistungen
Ein Dienst wird häufig verwendet, um Funktionen für die Nutzung durch andere Anwendungen bereitzustellen. Jede Serviceklasse muss eine entsprechende <service>-Deklaration in ihrer Manifestdatei haben.
Standardmäßig werden Dienste nicht exportiert und können von keiner anderen Anwendung aufgerufen werden. Wenn Sie der Dienstdeklaration jedoch Absichtsfilter hinzufügen, wird diese standardmäßig exportiert. Am besten deklarieren Sie das Attribut android:exported explizit, um sicherzustellen, dass es sich so verhält, wie Sie es beabsichtigen. Dienste können auch mit dem Attribut android:permission geschützt werden. Auf diese Weise müssen andere Anwendungen ein entsprechendes <uses-permission>-Element in ihrem eigenen Manifest deklarieren, um den Dienst starten, stoppen oder an ihn binden zu können.
Hinweis: Wenn Ihre App auf Android 5.0 (API-Level 21) oder höher abzielt, verwenden Sie den JobScheduler, um Hintergrunddienste auszuführen.
Ein Dienst kann einzelne an ihn gerichtete IPC-Aufrufe mit Berechtigungen schützen. Dies geschieht durch den Aufruf von checkCallingPermission() vor der Ausführung der Implementierung des Aufrufs. Wir empfehlen die Verwendung der deklarativen Berechtigungen im Manifest, da diese weniger anfällig für Versehen sind.
Achtung: Client- und Serverberechtigungen nicht verwechseln; Stellen Sie sicher, dass die aufgerufene App über die entsprechenden Berechtigungen verfügt, und stellen Sie sicher, dass Sie der aufrufenden App dieselben Berechtigungen erteilen.
Binder- und Messenger-Schnittstellen
Die Verwendung von Binder oder Messenger ist der bevorzugte Mechanismus für IPC im RPC-Stil unter Android. Sie stellen wohldefinierte Schnittstellen bereit, die bei Bedarf eine gegenseitige Authentifizierung der Endpunkte ermöglichen.
Wir empfehlen Ihnen, Ihre App-Schnittstellen so zu gestalten, dass keine schnittstellenspezifischen Berechtigungsprüfungen erforderlich sind. Binder- und Messenger-Objekte werden nicht im Anwendungsmanifest deklariert und daher können Sie deklarative Berechtigungen nicht direkt auf sie anwenden. Sie erben im Allgemeinen die Berechtigungen, die im Anwendungsmanifest für den Dienst oder die Aktivität, in der sie implementiert sind, deklariert sind. Wenn Sie eine Schnittstelle erstellen, die Authentifizierung und/oder Zugriffskontrollen erfordert, müssen Sie diese Kontrollen explizit als Code in der Binder- oder Messenger-Schnittstelle hinzufügen.
Wenn Sie eine Schnittstelle bereitstellen, die Zugriffskontrollen erfordert, überprüfen Sie mit checkCallingPermission(), ob der Aufrufer über die erforderliche Berechtigung verfügt. Dies ist besonders wichtig, bevor Sie im Namen des Aufrufers auf einen Dienst zugreifen, da die Identität Ihrer Anwendung an andere Schnittstellen weitergegeben wird. Wenn Sie eine von einem Dienst bereitgestellte Schnittstelle aufrufen, kann der Aufruf von bindService() fehlschlagen, wenn Sie keine Berechtigung zum Zugriff auf den angegebenen Dienst haben. Wenn Sie einem externen Prozess erlauben müssen, mit Ihrer App zu interagieren, dieser jedoch nicht über die erforderlichen Berechtigungen dafür verfügt, können Sie die Methode „clearCallingIdentity()“ verwenden. Diese Methode führt den Aufruf an die Schnittstelle Ihrer App so aus, als ob Ihre App den Aufruf selbst tätigen würde und nicht der externe Anrufer. Sie können die Anruferberechtigungen später mit der Methode „restoreCallingIdentity()“ wiederherstellen.
Weitere Informationen zum Durchführen von IPC mit einem Dienst finden Sie unter Gebundene Dienste.
Broadcast-Receiver
Ein Broadcast-Receiver verarbeitet asynchrone Anfragen, die von einem Verwender initiiert werden.
Standardmäßig werden Empfänger exportiert und können von jeder anderen Anwendung aufgerufen werden. Wenn Ihr Broadcast-Receiver für die Verwendung durch andere Anwendungen vorgesehen ist, möchten Sie möglicherweise Sicherheitsberechtigungen auf Empfänger anwenden, indem Sie das Empfänger-Element im Anwendungsmanifest verwenden. Dadurch wird verhindert, dass Anwendungen ohne entsprechende Berechtigungen eine Absicht an den Broadcast-Receiver senden.