OWASP-Kategorie: MASVS-CODE: Codequalität
Übersicht
Die mit benutzerdefinierten Berechtigungen verbundenen Risiken entstehen, wenn die Definition der benutzerdefinierten Berechtigungen fehlt oder falsch geschrieben ist oder wenn das entsprechende Attribut android:protectionLevel im Manifest missbraucht wird.
Diese Risiken können beispielsweise ausgenutzt werden, indem eine benutzerdefinierte Berechtigung mit demselben Namen erstellt wird, die jedoch von einer schädlichen App definiert wird und auf die unterschiedliche Schutzstufen angewendet werden.
Benutzerdefinierte Berechtigungen sollen die gemeinsame Nutzung von Ressourcen und Funktionen mit anderen Apps ermöglichen. Beispiele für die legitime Verwendung benutzerdefinierter Berechtigungen sind:
- Steuern der Interprozesskommunikation (IPC) zwischen zwei oder mehr Apps
- Zugriff auf Drittanbieterdienste
- Einschränken des Zugriffs auf die weitergegebenen Daten einer App
Auswirkungen
Wenn diese Sicherheitslücke ausgenutzt wird, kann eine schädliche App Zugriff auf Ressourcen erhalten, die ursprünglich geschützt werden sollten. Die Auswirkungen der Sicherheitslücke hängen von der geschützten Ressource und den zugehörigen Berechtigungen des ursprünglichen Anwendungsdienstes ab.
Risiko: Tippfehler bei benutzerdefinierten Berechtigungen
Eine benutzerdefinierte Berechtigung kann im Manifest deklariert werden. Aufgrund eines Tippfehlers wird jedoch eine andere benutzerdefinierte Berechtigung verwendet, um exportierte Android-Komponenten zu schützen. Eine schädliche Anwendung kann Anwendungen ausnutzen, bei denen eine Berechtigung falsch geschrieben wurde, indem sie entweder:
- diese Berechtigung zuerst registriert
- die Schreibweise in nachfolgenden Anwendungen vorwegnimmt
Dadurch kann eine Anwendung unbefugten Zugriff auf Ressourcen oder die Kontrolle über die Opferanwendung erhalten.
Beispiel: Eine anfällige App möchte eine Komponente mit der Berechtigung READ_CONTACTS schützen, schreibt die Berechtigung aber versehentlich als READ_CONACTS. Eine schädliche App kann READ_CONACTS beanspruchen, da sie keiner Anwendung (oder dem System) gehört, und Zugriff auf die geschützte Komponente erhalten. Eine weitere häufige Variante dieser Sicherheitslücke ist android:permission=True. Werte wie true und false sind unabhängig von der Groß-/Kleinschreibung ungültige Eingaben für die Berechtigungsdeklaration und werden ähnlich wie andere Tippfehler bei der Deklaration benutzerdefinierter Berechtigungen behandelt. Um dieses Problem zu beheben, muss der Wert des Attributs android:permission in einen gültigen Berechtigungsstring geändert werden. Wenn die App beispielsweise auf die Kontakte des Nutzers zugreifen muss, sollte der Wert des Attributs android:permission android.permission.READ_CONTACTS sein.
Gegenmaßnahmen
Android Lint-Prüfungen
Verwenden Sie beim Deklarieren benutzerdefinierter Berechtigungen Android Lint-Prüfungen, um Tippfehler und andere potenzielle Fehler in Ihrem Code zu finden.
Namenskonvention
Verwenden Sie eine konsistente Namenskonvention, damit Tippfehler leichter zu erkennen sind. Prüfen Sie die Deklarationen benutzerdefinierter Berechtigungen im Manifest Ihrer App sorgfältig auf Tippfehler.
Risiko: Verwaiste Berechtigungen
Berechtigungen werden verwendet, um Ressourcen von Apps zu schützen. Es gibt zwei verschiedene Orte, an denen eine App die Berechtigungen deklarieren kann, die für den Zugriff auf Ressourcen erforderlich sind:
- AndroidManifest.xml: Vordefiniert in der Datei AndroidManifest.xml (wenn nicht
angegeben, werden
<application>Berechtigungen verwendet), z.B. Berechtigung für Anbieter, Berechtigung für Empfänger, Berechtigung für Aktivität, Berechtigung für Dienst; - Code: Im Laufzeitcode registriert, z. B.
registerReceiver()
Manchmal werden diese Berechtigungen jedoch nicht durch ein entsprechendes
<permission> Tag im Manifest eines APK auf dem Gerät definiert. In diesem Fall werden sie als verwaiste Berechtigungen bezeichnet. Diese Situation kann aus verschiedenen Gründen auftreten, z. B.:
- Es kann eine Desynchronisierung zwischen Updates im Manifest und dem Code mit der Berechtigungsprüfung vorliegen.
- Das APK mit den Berechtigungen ist möglicherweise nicht im Build enthalten oder die falsche Version wurde verwendet.
- Der Berechtigungsname ist entweder in der Prüfung oder im Manifest falsch geschrieben.
Eine schädliche App könnte eine verwaiste Berechtigung definieren und erwerben. In diesem Fall könnten die privilegierten Anwendungen, die sich auf die verwaiste Berechtigung verlassen, um eine Komponente zu schützen, kompromittiert werden.
Wenn die privilegierte App die Berechtigung verwendet, um eine Komponente zu schützen oder einzuschränken, könnte die schädliche App Zugriff auf diese Komponente erhalten. Beispiele hierfür sind das Starten von Aktivitäten, die durch eine Berechtigung geschützt sind, der Zugriff auf einen Contentanbieter oder das Senden an einen Übertragungsempfänger, der durch die verwaiste Berechtigung geschützt ist.
Es könnte auch eine Situation entstehen, in der die privilegierte Anwendung getäuscht wird und annimmt, dass die schädliche App eine legitime App ist, und daher Dateien oder Inhalte lädt.
Gegenmaßnahmen
Achten Sie darauf, dass alle benutzerdefinierten Berechtigungen, die Ihre App zum Schutz von Komponenten verwendet, auch im Manifest definiert sind.
Die App verwendet die benutzerdefinierten Berechtigungen my.app.provider.READ und my.app.provider.WRITE, um den Zugriff auf einen Contentanbieter zu schützen:
Xml
<provider android:name="my.app.database.CommonContentProvider" android:readPermission="my.app.provider.READ" android:writePermission="my.app.provider.WRITE" android:exported="true" android:process=":myappservice" android:authorities="my.app.database.contentprovider"/>
Die App definiert und verwendet diese benutzerdefinierten Berechtigungen auch, um zu verhindern, dass andere schädliche Apps dies tun:
Xml
<permission android:name="my.app.provider.READ"/>
<permission android:name="my.app.provider.WRITE"/>
<uses-permission android:name="my.app.provider.READ" />
<uses-permission android:name="my.app.provider.WRITE" />
Risiko: Missbrauch von android:protectionLevel
Dieses Attribut beschreibt das potenzielle Risikoniveau der Berechtigung und gibt an, welche Schritte das System ausführen sollte, wenn es entscheidet, ob die Berechtigung gewährt werden soll oder nicht.
Gegenmaßnahmen
Schutzstufe „Normal“ oder „Gefährlich“ vermeiden
Wenn Sie für Ihre Berechtigungen eine protectionLevel von normal oder dangerous verwenden, können die meisten Apps die Berechtigung anfordern und erhalten:
- Bei „normal“ muss sie nur deklariert werden.
- „dangerous“ wird von vielen Nutzern genehmigt.
Daher bieten diese protectionLevels nur wenig Sicherheit.
Signaturberechtigungen verwenden (Android >= 10)
Verwenden Sie nach Möglichkeit Schutzstufen für Signaturen. Dadurch wird sichergestellt, dass nur andere Apps, die mit demselben Zertifikat wie die App signiert sind, die die Berechtigung erstellt hat, auf diese geschützten Funktionen zugreifen können. Achten Sie darauf, dass Sie ein dediziertes (nicht wiederverwendetes) Signaturzertifikat verwenden und es sicher in einem Schlüsselspeicheraufbewahren.
Definieren Sie eine benutzerdefinierte Berechtigung wie folgt im Manifest:
Xml
<permission
android:name="my.custom.permission.MY_PERMISSION"
android:protectionLevel="signature"/>
Beschränken Sie den Zugriff auf z.B. eine Aktivität auf Apps, denen diese benutzerdefinierte Berechtigung gewährt wurde, wie folgt:
Xml
<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>
Jede andere App, die mit demselben Zertifikat wie die App signiert ist, die diese benutzerdefinierte Berechtigung deklariert hat, erhält dann Zugriff auf die Aktivität .MyActivity und muss sie wie folgt im Manifest deklarieren:
Xml
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
Vorsicht bei benutzerdefinierten Signaturberechtigungen (Android < 10)
Wenn Ihre App auf Android < 10 ausgerichtet ist, können schädliche Apps möglicherweise weiterhin die benutzerdefinierten Berechtigungen Ihrer App verwenden und so Prüfungen umgehen, wenn die benutzerdefinierten Berechtigungen Ihrer App aufgrund von Deinstallationen oder Updates entfernt werden. Dies ist auf eine
Sicherheitslücke zur Rechteausweitung (CVE-2019-2200) zurückzuführen, die
in Android 10 behoben wurde.
Dies ist einer der Gründe (neben dem Risiko von Race-Bedingungen), warum Signaturprüfungen gegenüber benutzerdefinierten Berechtigungen empfohlen werden.
Risiko: Race-Bedingung
Wenn eine legitime App A eine benutzerdefinierte Signaturberechtigung definiert, die von anderen X-Apps verwendet wird, sie aber anschließend deinstalliert wird, kann eine schädliche App B dieselbe benutzerdefinierte Berechtigung mit einer anderen protectionLevel definieren, z.B. normal. Auf diese Weise erhält B Zugriff auf alle Komponenten, die durch diese benutzerdefinierte Berechtigung in den X-Apps geschützt sind, ohne mit demselben Zertifikat wie die App A signiert sein zu müssen.
Dasselbe passiert, wenn B vor A installiert wird.
Gegenmaßnahmen
Wenn Sie eine Komponente nur für Apps verfügbar machen möchten, die mit derselben Signatur wie die bereitstellende App signiert sind, können Sie möglicherweise vermeiden, benutzerdefinierte Berechtigungen zu definieren, um den Zugriff auf diese Komponente einzuschränken. In diesem Fall können Sie Signaturprüfungen verwenden. Wenn eine Ihrer Apps eine Anfrage an eine andere Ihrer Apps sendet, kann die zweite App prüfen, ob beide Apps mit demselben Zertifikat signiert sind, bevor sie die Anfrage bearbeitet.
Ressourcen
- Berechtigungsanfragen minimieren
- Übersicht über Berechtigungen
- Beschreibung der Schutzstufen
- CustomPermissionTypo Android Lint
- Android Lint verwenden
- Forschungsarbeit mit detaillierter Erklärung der Android-Berechtigungen und interessanten Ergebnissen von Fuzz-Tests