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.

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_SYSTEMbewertet.
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:

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 detaillierteUpdateCheckResultzusammen 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
- 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 mitWorkManager(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. - Hintergrund-Threading:Rufen Sie
loadVulnerabilityReport()in einem Hintergrundthread (Dispatchers.IOin Kotlin oderExecutorin Java) auf, um zu vermeiden, dass der Haupt-UI-Thread beim Parsen von CVE-Einträgen blockiert wird. - Kernel LTS-Bewertung:Beim Aufrufen von
getPatchedCves(COMPONENT_KERNEL, ...)wird eineIllegalArgumentExceptionausgelöst und mitareCvesPatched()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 vongetPublishedSecurityPatchLevel(COMPONENT_KERNEL)zurückgegeben werden und mit dem Haupt- und Nebenbranch übereinstimmen (z.B. einen5.15.140-Kernel mit dem5.15.159-Ziel vergleichen).
Zusätzliche Ressourcen
Weitere Informationen zum Gerätesicherheitsstatus finden Sie in den folgenden Ressourcen:
Dokumentation
- Sicherheitsbulletins für Android
- Modulare Systemkomponenten
- Generic Kernel Image (GKI)
- Zusätzliche Sicherheitspatches
- Play Integrity API
- OSV-Datenbank (Open Source Vulnerabilities)
- Versionshinweise für Security State 1.1.0