Gerätesicherheitsstatus

Ihre App ist nur so sicher wie das zugrunde liegende Betriebssystem. Um das Risiko zu minimieren, sollten sicherheitssensible Vorgänge in Ihrer App durch eine Echtzeitbewertung des Sicherheitsstatus des Geräts geschützt werden. Dabei wird ermittelt, ob das Gerät, insbesondere seine Kernsystemkomponenten, vollständig aktualisiert und vor Sicherheitslücken geschützt ist, die im Sicherheitsbulletin für Android veröffentlicht wurden. Die Sichtbarkeit des Sicherheitsstatus des Geräts hilft Ihnen, Sicherheitsmaßnahmen zu ergreifen, bevor Ihre App risikoreiche Vorgänge ausführt.

AndroidX Security State ist eine Jetpack-Bibliothek, die einheitlichen Zugriff auf den Sicherheitsstatus eines Android-Geräts bietet. Dabei werden AOSP-APIs und öffentliche Android-Sicherheitslücken-Feeds kombiniert, um einen umfassenden, präzisen und umsetzbaren Gerätesicherheitsstatus zu liefern, der über das Sicherheitspatch-Level (SPL) hinausgeht.

Architekturübersicht

Das folgende Diagramm veranschaulicht, wie die AndroidX Security State-Bibliothek On-Device-Plattformattribute, IPC-Updateanbieter (Interprocess Communication) und öffentliche Sicherheitslückenfeeds in einem einzigen, zusammenhängenden Satz von APIs vereint.

Die AndroidX Security State-Bibliothek vereinheitlicht On-Device-Plattformattribute, IPC-Update-Anbieter und öffentliche Sicherheitslücken-Feeds in einer Reihe einheitlicher APIs.

Status und Komponenten von Sicherheitspatches

Der Hauptvorteil der Verwendung der Security State-Bibliothek besteht darin, dass sie das Security Patch Level (SPL) auf granularer Komponentenebene bereitstellen kann. Im Laufe der Jahre wurden in Android immer mehr Module für Google Play-Systemupdates (Project Mainline) eingeführt. Diese werden über Google Play unabhängig von den standardmäßigen System-OTA-Updates aktualisiert und bieten wichtige Sicherheitskorrekturen in einem anderen Rhythmus.

Während das Sicherheitspatch-Level in der Regel die mindestens erforderliche Generic Kernel Image (GKI)-Version vorschreibt, können Kernel-Updates tatsächlich vor dem Systemzeitplan erfolgen. Diese kernelspezifischen Korrekturen werden möglicherweise nicht vollständig durch den primären SPL-String des Systems erfasst.

Zur Verbesserung der Transparenz bietet die Sicherheitsstatusbibliothek für alle drei Komponenten einen effektiven Patch-Level:

  • System (COMPONENT_SYSTEM): Stellt den Standardstatus des Betriebssystems und der Systemsicherheit dar, der aus dem Standardfeld für das Sicherheitspatch-Level abgeleitet wird.
  • System-Mainline-Module (COMPONENT_SYSTEM_MODULES): Stellt den Sicherheitsstatus der modularen Systemkomponenten (Google Play-Systemupdates) dar, der aus bestimmten Modul-Release-Versionen abgeleitet wird.
  • Kernel (COMPONENT_KERNEL): Stellt den Sicherheitsstatus des Geräte-Kernels dar, der direkt aus dem Kernel-Versionsstring abgeleitet wird.

Je nach Komponente bietet die Bibliothek bis zu drei Dimensionen von Patchlevel-Informationen:

  • Geräte-Sicherheitskorrekturebene (Device Security Patch Level, DSPL): Die aktuelle Sicherheitskorrekturebene einzelner Komponenten, die auf dem Gerät ausgeführt werden. Sie wird synchron ohne Netzwerkanfragen abgerufen. System- und Mainline-Berichte enthalten Kalenderdaten (DateBasedSecurityPatchLevel), während der Kernel seine Release-Version (z. B. VersionedSecurityPatchLevel, 5.15.148) meldet.
  • Veröffentlichte SPL (PSPL): Die Baseline, die offiziell im Android-Sicherheitsbulletin und in Berichten zur OSV-Datenbank (Open Source Vulnerabilities) veröffentlicht wird. Ihre App kann die Konformität prüfen, indem sie Datumsangaben oder Versionsstrings vergleicht, die vom Geräte-SPL bereitgestellt werden.
  • Verfügbare SPL (ASPL): Gibt an, ob für ein Gerät ausstehende Updates von Updateanbietern verfügbar sind, die asynchron über IPC abgefragt werden. Die Funktion „Android Google Play-Systemupdate“ bietet Verfügbarkeit für Mainline-Module und OEM-OTA-Clients bieten Verfügbarkeit für Systemupdates. Da Kernel-Updates im Betriebssystem-Image enthalten sind, wird die Verfügbarkeit von Kernel-Updates anhand von COMPONENT_SYSTEM bewertet.

Sicherheitskritische Funktionen einschränken

Sie können Informationen aus DSPL (Device SPL), ASPL (Available SPL) und PSPL (Published SPL) kombinieren, um kontextbezogene Entscheidungen für die Beschränkung sicherheitssensibler Funktionen zu treffen. Sie können beispielsweise DSPL mit ASPL vergleichen, um festzustellen, ob ein neuerer Sicherheitspatch verfügbar ist, den der Nutzer noch nicht installiert hat. In diesem Fall können Sie ihn auffordern, ein Update durchzuführen, bevor er sensible Vorgänge wie Zahlungen oder die Registrierung von Anmeldedaten startet. Sie können areCvesPatched() auch verwenden, um zu prüfen, ob bestimmte, risikoreiche Sicherheitslücken auf dem Gerät behoben wurden, bevor anfällige Subsysteme aufgerufen werden. So können Sie beispielsweise vor der Autorisierung von Zahlungen oder der Datenfreigabe in der Nähe prüfen, ob kritische NFC- oder Bluetooth-Sicherheitslücken vorhanden sind.

Hinweise zur Plattformversion

Bestimmte Funktionen für den Sicherheitsstatus hängen von der zugrunde liegenden Plattformarchitektur ab und sind in niedrigeren Android-Versionen nicht verfügbar:

  • Android 11 (API-Level 30) und höher:Volle Unterstützung für alle Komponenten, einschließlich der im Bulletin veröffentlichten Kernel-LTS-Versionen und Verfügbarkeitsabfragen für Updates (ASPL).
  • Android 10 (API-Level 29): Unterstützt Patch-Levels für System und Systemmodule. Im Bulletin veröffentlichte Kernelversionen sind jedoch nicht verfügbar, da die GKI-Nachverfolgung (Generic Kernel Image) und die LTS-Ziele (Long-Term Support) für den Kernel im Android-Sicherheitsbulletin erst in Android 11 eingeführt wurden. Die Kernelversion auf dem Gerät kann weiterhin lokal gelesen werden.
  • Android 9 (API‑Level 28) und älter:Zusätzlich zu den Einschränkungen von Android 10 gab es vor Android 10 keine modularen Systemkomponenten (Project Mainline). Der Aufruf von getDeviceSecurityPatchLevel(COMPONENT_SYSTEM_MODULES) wird sicher auf das Unix-Epoche-Basisdatum (1970-01-01) zurückgesetzt, wenn SPLs für Systemmodule nicht verfügbar sind.

Verfügbarkeit von Updates und verfügbare Sicherheitskorrekturebene (Available SPL, ASPL)

Um den Sicherheitsstatus eines Geräts zu ermitteln, muss bekannt sein, ob für einzelne Komponenten ausstehende Sicherheitsupdates verfügbar sind. Android-Geräte erhalten Sicherheitsupdates über verschiedene Bereitstellungsmechanismen, z. B. Over-the-Air-Systemupdates (OTA) und Google Play-Systemupdates für modulare Komponenten.

Bevor Ihre App die ASPL für eine bestimmte Komponente abrufen kann, muss der entsprechende Updateanbieter diese Informationen veröffentlichen. Um diese verschiedenen Updatequellen zu koordinieren, verwenden Clientanwendungen die AndroidX Security State-Bibliothek, um den Sicherheitsstatus abzufragen. On-Device-Updateclients verwenden die zugehörige AndroidX Security State Provider-Bibliothek, um ihr verfügbares Sicherheitspatch-Level (Available Security Patch Level, ASPL) zu veröffentlichen.

Google stellt für alle GMS-Android-Geräte Updateinformationen für Mainline-Module sowie System-OTA-Informationen für Geräte mit dem Google-OTA-Client (GOTA) bereit.

Das folgende Diagramm zeigt, wie Clientanwendungen die AndroidX Security State-Bibliothek verwenden, um den Sicherheitsstatus sowohl für Google Play-Systemupdates als auch für OTA-Systemupdates abzufragen:

Clientanwendungen verwenden die AndroidX Security State-Bibliothek, um den Sicherheitsstatus sowohl für Google Play-Systemupdates als auch für OTA-Systemupdates abzufragen.

Abhängigkeiten hinzufügen

Wenn Sie eine Abhängigkeit von AndroidX Security State hinzufügen möchten, müssen Sie das Google Maven-Repository in Ihr Projekt einfügen. Fügen Sie die Abhängigkeit der Datei build.gradle.kts oder build.gradle Ihrer App hinzu:

Kotlin

// Kotlin DSL (build.gradle.kts)
dependencies {
    implementation("androidx.security:security-state:1.1.0")
}

Groovy

// Groovy DSL (build.gradle)
dependencies {
    implementation "androidx.security:security-state:1.1.0"
}

Matrix der deklarierten Berechtigungen

Ziel-APIs Erforderliche Berechtigungen in der AndroidManifest.xml Operative Hinweise
getDeviceSecurityPatchLevel() Keine Liest lokale native Systemeigenschaften und Paketmetadaten synchron.
fetchAvailableSecurityPatchLevel()
queryAllAvailableUpdates()
Keine Kommuniziert über die geräteinterne IPC. Die Bibliothek fragt nur vertrauenswürdige Komponenten auf dem Gerät ab. Dazu benötigen Updateanbieter die Berechtigung READ_PRIVILEGED_PHONE_STATE. Ihre App kann sich also auf die Authentizität der empfangenen Informationen verlassen.
createVulnerabilityReportUrl()
loadVulnerabilityReport()
getPublishedSecurityPatchLevel()
areCvesPatched()
isDeviceFullyUpdated()
android.permission.INTERNET Erforderlich, um öffentliche OSV-Berichte abzurufen. Sobald die Daten mit loadVulnerabilityReport() in den Arbeitsspeicher geladen wurden, werden Abfragemethoden lokal ohne Netzwerkzugriff ausgeführt.

Bibliothek initialisieren

Initialisieren Sie SecurityPatchState mit einem Android-Context:

Kotlin

import androidx.security.state.SecurityPatchState

val securityPatchState = SecurityPatchState(context)

Java

import androidx.security.state.SecurityPatchState;

SecurityPatchState securityPatchState = new SecurityPatchState(context);

Durch die Initialisierung mit context allein wird sofortiger Zugriff auf Offline-Geräte-Patch-Ebenen ohne Netzwerkabhängigkeiten ermöglicht. (Update-Verfügbarkeitsanfragen werden asynchron mit On-Device-Anbietern kommuniziert.)

Wenn in Ihrer App die CVE-Konformität geprüft wird und bereits ein OSV-Sicherheitslückenbericht in den Arbeitsspeicher geladen wurde, können Kotlin-Aufrufer den JSON-String direkt an den Konstruktor in Kotlin übergeben:

val securityPatchState = SecurityPatchState(context, vulnerabilityReportJsonString = jsonString)

In Java oder beim asynchronen Laden von Berichten nach dem Start initialisieren Sie mit dem Kontext und rufen Sie securityPatchState.loadVulnerabilityReport(jsonString) auf.

Patch-Level des Geräts prüfen

Synchrones Abfragen von Patch-Levels auf dem Gerät:

Kotlin

val deviceSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM)
val mainlineSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM_MODULES)
val kernelVersion = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_KERNEL)

// Gatekeeping check: compare against a required baseline patch date
val requiredSpl = SecurityPatchState.DateBasedSecurityPatchLevel.fromString("2026-01-01")
if (deviceSpl < requiredSpl) {
    // Restrict access to sensitive features or guide user to update
}

Java

SecurityPatchState.SecurityPatchLevel deviceSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM);
SecurityPatchState.SecurityPatchLevel mainlineSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM_MODULES);
SecurityPatchState.SecurityPatchLevel kernelVersion = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_KERNEL);

// Gatekeeping check: compare against a required baseline patch date
SecurityPatchState.SecurityPatchLevel requiredSpl = SecurityPatchState.DateBasedSecurityPatchLevel.fromString("2026-01-01");
if (deviceSpl.compareTo(requiredSpl) < 0) {
    // Restrict access to sensitive features or guide user to update
}

Nach ausstehenden Systemupdates suchen

Apps können die Verfügbarkeit ausstehender Updates ermitteln, indem sie asynchron mit vertrauenswürdigen Updateanbietern auf dem Gerät kommunizieren. Das sind in der Regel Google Play-Systemupdates und OEM-OTA-Clients:

  • fetchAvailableSecurityPatchLevel(): Gibt die effektive verfügbare SPL für eine bestimmte Komponente zurück (falls kein neueres Update verfügbar ist, wird auf die aktuelle Geräte-SPL zurückgegriffen), die zum Vergleich mit der Geräte-SPL und der veröffentlichten SPL verwendet werden kann.
  • queryAllAvailableUpdates(): Ermittelt alle vertrauenswürdigen Updateanbieter auf dem Gerät und gibt detaillierte UpdateCheckResult zusammen mit Metadaten zur Quelle und Aktualität der Daten zurück.

Beispiel 1: Nutzer zu ausstehenden Updates auffordern

Verwenden Sie fetchAvailableSecurityPatchLevel(), um Nutzer zu benachrichtigen, wenn Sicherheitsupdates verfügbar sind (z. B. durch Starten von Settings.ACTION_SYSTEM_UPDATE_SETTINGS):

Kotlin

import androidx.lifecycle.lifecycleScope
import androidx.security.state.SecurityPatchState
import kotlinx.coroutines.launch

// Pattern A: Prompt users for pending updates (with automatic offline fallback)
lifecycleScope.launch {
    val currentSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM)
    val availableSpl = securityPatchState.fetchAvailableSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM)
    if (availableSpl > currentSpl) {
        // Prompt the user to install pending updates in system settings
    }
}

Java

In Java geben asynchrone Methoden ein ListenableFuture zurück und leiten Callbacks über ContextCompat.getMainExecutor() weiter:

import androidx.core.content.ContextCompat;
import androidx.security.state.SecurityPatchState;
import androidx.security.state.SecurityPatchState.SecurityPatchLevel;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

// Pattern A: Prompt users for pending updates (with automatic offline fallback)
SecurityPatchLevel currentSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM);
ListenableFuture<SecurityPatchLevel> availableSpl = securityPatchState.fetchAvailableSecurityPatchLevelAsync(
    SecurityPatchState.COMPONENT_SYSTEM,
    SecurityPatchState.UPDATE_INFO_SERVICE_BINDING_TIMEOUT_MS
);

Futures.addCallback(availableSpl, new FutureCallback<SecurityPatchLevel>() {
    @Override
    public void onSuccess(SecurityPatchLevel available) {
        if (available.compareTo(currentSpl) > 0) {
            // Prompt the user to install pending updates in system settings
        }
    }

    @Override
    public void onFailure(Throwable t) {
        // Handle timeout or IPC communication error
    }
}, ContextCompat.getMainExecutor(context));

Beispiel 2: Detaillierten Anbieterstatus prüfen

Verwenden Sie queryAllAvailableUpdates(), um einzelne Anbieter, Zeitstempel und UpdateInfo-Datensätze zu prüfen:

Kotlin

import androidx.lifecycle.lifecycleScope
import androidx.security.state.SecurityPatchState
import kotlinx.coroutines.launch

// Pattern B: Inspect detailed provider status
lifecycleScope.launch {
    val updateResults = securityPatchState.queryAllAvailableUpdates()
    for (result in updateResults) {
        val provider = result.providerPackageName
        val lastCheck = result.lastCheckTimeMillis
        val updates = result.updates // List<UpdateInfo>
    }
}

Java

import androidx.core.content.ContextCompat;
import androidx.security.state.SecurityPatchState;
import androidx.security.state.UpdateCheckResult;
import androidx.security.state.UpdateInfo;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;

// Pattern B: Inspect detailed provider status
ListenableFuture<List<UpdateCheckResult>> updateResults = securityPatchState.queryAllAvailableUpdatesAsync(
    SecurityPatchState.UPDATE_INFO_SERVICE_BINDING_TIMEOUT_MS
);

Futures.addCallback(updateResults, new FutureCallback<List<UpdateCheckResult>>() {
    @Override
    public void onSuccess(List<UpdateCheckResult> results) {
        for (UpdateCheckResult result : results) {
            String provider = result.getProviderPackageName();
            long lastCheck = result.getLastCheckTimeMillis();
            List<UpdateInfo> updates = result.getUpdates();
        }
    }

    @Override
    public void onFailure(Throwable t) {
        // Handle error
    }
}, ContextCompat.getMainExecutor(context));

Behebung von Sicherheitslücken überprüfen und CVEs prüfen

Wenn Sie CVE-Schutzmaßnahmen bewerten, die allgemeine Update-Compliance prüfen oder veröffentlichte Sicherheitspatch-Levels (Published Security Patch Levels, PSPL) untersuchen möchten, muss Ihre App zuerst einen OSV-Sicherheitslückenbericht abrufen und laden. Weitere Informationen finden Sie in der API-Referenz für SecurityPatchState.

Kotlin

// Load vulnerability report
val reportUrl = SecurityPatchState.createVulnerabilityReportUrl()
// ... download JSON string from reportUrl ...
securityPatchState.loadVulnerabilityReport(jsonString)

// Check overall update compliance against published bulletin
val isFullyUpdated = securityPatchState.isDeviceFullyUpdated()

val cves = listOf("CVE-2019-9501", "CVE-2020-3699", "CVE-2024-0016")
val isPatched = securityPatchState.areCvesPatched(cves)

// Get a list of all patched CVEs for a specific component and SPL
val deviceSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM)
val patchedSystemCVEs = securityPatchState.getPatchedCves(SecurityPatchState.COMPONENT_SYSTEM, deviceSpl)

// Inspect published SPL and kernel LTS target versions from the bulletin
val publishedSystemSpl = securityPatchState.getPublishedSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM)
val kernelLtsTargets = securityPatchState.getPublishedSecurityPatchLevel(SecurityPatchState.COMPONENT_KERNEL)

Java

// Load vulnerability report
Uri reportUrl = SecurityPatchState.createVulnerabilityReportUrl();
// ... download JSON string from reportUrl ...
securityPatchState.loadVulnerabilityReport(jsonString);

// Check overall update compliance against published bulletin
boolean isFullyUpdated = securityPatchState.isDeviceFullyUpdated();

List<String> cves = Arrays.asList("CVE-2019-9501", "CVE-2020-3699", "CVE-2024-0016");
boolean isPatched = securityPatchState.areCvesPatched(cves);

// Get a list of all patched CVEs for a specific component and SPL
SecurityPatchState.SecurityPatchLevel deviceSpl = securityPatchState.getDeviceSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM);
Map<SecurityPatchState.Severity, Set<String>> patchedSystemCVEs =
    securityPatchState.getPatchedCves(SecurityPatchState.COMPONENT_SYSTEM, deviceSpl);

// Inspect published SPL and kernel LTS target versions from the bulletin
List<SecurityPatchState.SecurityPatchLevel> publishedSystemSpl =
    securityPatchState.getPublishedSecurityPatchLevel(SecurityPatchState.COMPONENT_SYSTEM);
List<SecurityPatchState.SecurityPatchLevel> kernelLtsTargets =
    securityPatchState.getPublishedSecurityPatchLevel(SecurityPatchState.COMPONENT_KERNEL);

Berichte zu Sicherheitslücken laden

  1. Lokales Caching und WorkManager-Aktualisierung:Da Android-Sicherheitsbulletins monatlich veröffentlicht werden, sollten Sie die heruntergeladene JSON-Datei im internen Speicher (context.filesDir) zwischenspeichern und mit WorkManager (vorzugsweise alle 24–48 Stunden) eine regelmäßige Hintergrundaufgabe planen, um den Bericht zu aktualisieren. Beim Start der App wird synchron aus dem lokalen Cache gelesen.
  2. Hintergrund-Threading:Rufen Sie loadVulnerabilityReport() in einem Hintergrundthread (Dispatchers.IO in Kotlin oder Executor in Java) auf, um zu vermeiden, dass der Haupt-UI-Thread beim Parsen von CVE-Einträgen blockiert wird.
  3. Kernel LTS-Bewertung:Beim Aufrufen von getPatchedCves(COMPONENT_KERNEL, ...) wird eine IllegalArgumentException ausgelöst und mit areCvesPatched() werden keine Kernel-CVEs ausgewertet. Bewerten Sie stattdessen die Kernelsicherheit, indem Sie die Kernelversion des Geräts mit den Android Common Kernel LTS-Zielen vergleichen, die von getPublishedSecurityPatchLevel(COMPONENT_KERNEL) zurückgegeben werden und mit dem Haupt- und Nebenbranch übereinstimmen (z.B. einen 5.15.140-Kernel mit dem 5.15.159-Ziel vergleichen).

Zusätzliche Ressourcen

Weitere Informationen zum Gerätesicherheitsstatus finden Sie in den folgenden Ressourcen:

Dokumentation

API-Referenz