A segurança do seu app depende do SO em que ele é executado. Para reduzir o risco, o app precisa restringir operações sensíveis à segurança com uma avaliação em tempo real da postura de segurança do dispositivo, determinando se o dispositivo, especialmente os componentes principais do sistema, está totalmente atualizado e protegido contra vulnerabilidades publicadas no Boletim de segurança do Android. A visibilidade do estado de segurança do dispositivo ajuda a estabelecer proteções antes que o app execute operações de alto risco.
O AndroidX Security State é uma biblioteca do Jetpack que oferece acesso unificado ao estado de segurança de um dispositivo Android. Ele combina APIs do AOSP e feeds públicos de vulnerabilidade do Android para fornecer um status de segurança do dispositivo abrangente, preciso e útil, além do nível do patch de segurança (SPL, na sigla em inglês).
Visão geral da arquitetura
O diagrama a seguir ilustra como a biblioteca AndroidX Security State unifica propriedades da plataforma no dispositivo, provedores de atualização de comunicação entre processos (IPC) e feeds de vulnerabilidade pública em um único conjunto coeso de APIs.

Estados e componentes do patch de segurança
A principal vantagem de usar a biblioteca Security State é a capacidade de fornecer o nível do patch de segurança (SPL, na sigla em inglês) em um nível granular de componente. Ao longo dos anos, o Android introduziu mais módulos nas atualizações do sistema do Google Play (Projeto Mainline), que são atualizadas usando o Google Play de forma independente das atualizações do sistema over-the-air (OTA) padrão, fornecendo correções de segurança críticas em uma cadência diferente.
Da mesma forma, embora o nível do patch de segurança geralmente exija a versão mínima necessária da imagem genérica do kernel (GKI), as atualizações do kernel podem avançar em relação à programação do sistema. Essas correções específicas do kernel podem não ser totalmente capturadas pela string SPL principal do sistema.
Para melhorar a transparência, a biblioteca de estado de segurança fornece um nível de patch efetivo para todos os três componentes individualmente:
- Sistema (
COMPONENT_SYSTEM): representa o status padrão de segurança do SO e do sistema derivado do campo de nível do patch de segurança padrão. - Módulos Mainline do sistema (
COMPONENT_SYSTEM_MODULES): representa o status de segurança dos componentes modulares do sistema (atualizações do sistema do Google Play), derivado de versões de lançamento de módulos específicos. - Kernel (
COMPONENT_KERNEL): representa o status de segurança do kernel do dispositivo, derivado diretamente da string de versão do kernel.
Dependendo do componente, a biblioteca fornece até três dimensões de informações no nível do patch:
- Nível de patch do dispositivo (DSPL): o nível de patch atual de componentes individuais
em execução no dispositivo, consultado de forma síncrona sem solicitações de rede. O sistema
e o Mainline informam datas do calendário (
DateBasedSecurityPatchLevel), enquanto o kernel informa a versão de lançamento (VersionedSecurityPatchLevel, por exemplo,5.15.148). - SPL publicado (PSPL): o valor de referência publicado oficialmente no Boletim de segurança do Android e nos relatórios do banco de dados de vulnerabilidades de código aberto (OSV). Seu app pode avaliar a conformidade comparando datas ou strings de versão fornecidas pelo SPL do dispositivo.
- SPL disponível (ASPL): indica se um dispositivo tem atualizações pendentes
disponíveis de provedores de atualização, consultadas de forma assíncrona usando IPC. O recurso de atualização do sistema do Google Play do Android oferece disponibilidade para módulos Mainline, e os clientes OTA do OEM oferecem disponibilidade para atualizações do sistema. Como as atualizações do kernel são agrupadas na imagem do sistema operacional, a disponibilidade de atualizações do kernel é avaliada usando
COMPONENT_SYSTEM.
Controlar recursos sensíveis à segurança
É possível combinar informações do DSPL, ASPL e PSPL para fazer determinações contextuais para o controle de recursos sensíveis à segurança. Por exemplo, é possível comparar DSPL e ASPL para determinar se há um patch de segurança mais recente disponível que o usuário ainda não instalou, pedindo que ele atualize antes de iniciar operações sensíveis, como pagamentos ou registro de credenciais. Você também pode usar o areCvesPatched() para
verificar se vulnerabilidades específicas de alto risco foram corrigidas no
dispositivo antes de invocar subsistemas vulneráveis, como verificar vulnerabilidades críticas de NFC
ou Bluetooth antes de autorizar pagamentos ou compartilhamento de dados
por proximidade.
Considerações sobre a versão da plataforma
Alguns recursos de estado de segurança dependem da arquitetura da plataforma e não estão disponíveis em versões mais antigas do Android:
- Android 11 (nível 30 da API) e versões mais recentes:suporte total a todos os componentes, incluindo versões LTS do kernel publicadas no boletim e consultas de disponibilidade de atualização (ASPL).
- Android 10 (nível 29 da API): oferece suporte a níveis de patch do sistema e do módulo do sistema. No entanto, as versões do kernel publicadas no boletim não estão disponíveis porque o rastreamento da imagem genérica do kernel (GKI) e as metas de LTS do kernel no Boletim de segurança do Android começaram no Android 11. A versão do kernel no dispositivo ainda pode ser lida localmente.
- Android 9 (nível 28 da API) e versões anteriores:além das limitações do Android 10, os componentes modulares do sistema (Projeto Mainline) não existiam antes do Android 10.
A chamada de
getDeviceSecurityPatchLevel(COMPONENT_SYSTEM_MODULES)volta com segurança para a data da época Unix de referência (1970-01-01) quando os SPLs do módulo do sistema não estão disponíveis.
Entender a disponibilidade de atualizações e o SPL disponível (ASPL)
Para determinar a postura de segurança de um dispositivo, é necessário saber se há atualizações de segurança pendentes disponíveis para componentes individuais. Os dispositivos Android recebem atualizações de segurança por vários mecanismos de entrega distintos, como atualizações de sistema over-the-air (OTA) e atualizações do sistema do Google Play para componentes modulares.
Antes que seu app possa recuperar o ASPL de um determinado componente, o provedor de atualização correspondente precisa publicar essas informações. Para coordenar essas diferentes fontes de atualização, os aplicativos cliente usam a biblioteca AndroidX Security State para consultar o estado de segurança, enquanto os clientes de atualização no dispositivo usam a biblioteca complementar AndroidX Security State Provider para publicar o nível do patch de segurança disponível (ASPL, na sigla em inglês).
O Google fornece informações de atualização para módulos Mainline a todos os dispositivos Android do GMS, bem como informações de OTA do sistema para dispositivos que usam o cliente OTA do Google (GOTA).
O diagrama a seguir ilustra como os aplicativos cliente usam a biblioteca AndroidX Security State para consultar a postura de segurança em atualizações do sistema do Google Play e atualizações OTA do sistema:

Adicionar dependências
Para adicionar uma dependência ao estado de segurança do AndroidX, inclua o repositório Maven do Google no seu projeto. Adicione a dependência ao arquivo
build.gradle.kts ou build.gradle do app:
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"
}
Matriz de permissões declaradas
| APIs de destino | Permissões necessárias no AndroidManifest.xml |
Observações operacionais |
|---|---|---|
getDeviceSecurityPatchLevel() |
Nenhum | Lê de forma síncrona as propriedades nativas do sistema e os metadados do pacote locais. |
fetchAvailableSecurityPatchLevel()queryAllAvailableUpdates() |
Nenhum | Comunicação usando IPC no dispositivo. A biblioteca só consulta componentes confiáveis no dispositivo (exigindo que os provedores de atualização tenham a permissão privilegiada READ_PRIVILEGED_PHONE_STATE), para que seu app possa confiar na autenticidade das informações recebidas. |
createVulnerabilityReportUrl()loadVulnerabilityReport()getPublishedSecurityPatchLevel()areCvesPatched()isDeviceFullyUpdated() |
android.permission.INTERNET |
Obrigatório para buscar relatórios públicos de OSV. Depois de carregados na memória usando loadVulnerabilityReport(), os métodos de consulta são executados localmente sem acesso à rede. |
Inicializar a biblioteca
Inicialize SecurityPatchState com um Context do Android:
Kotlin
import androidx.security.state.SecurityPatchState
val securityPatchState = SecurityPatchState(context)
Java
import androidx.security.state.SecurityPatchState;
SecurityPatchState securityPatchState = new SecurityPatchState(context);
A inicialização apenas com context oferece acesso imediato aos níveis de patch do dispositivo off-line sem dependências de rede. (Atualizar consultas de disponibilidade
se comunicar de forma assíncrona com provedores no dispositivo).
Se o app avaliar a conformidade com CVE e já tiver carregado um relatório de vulnerabilidade do OSV na memória, os chamadores do Kotlin poderão transmitir a string JSON diretamente para o construtor em Kotlin:
val securityPatchState = SecurityPatchState(context, vulnerabilityReportJsonString = jsonString)
Em Java ou ao carregar relatórios de forma assíncrona após a inicialização, inicialize com
contexto e chame securityPatchState.loadVulnerabilityReport(jsonString).
Verificar os níveis de patch do dispositivo
Consultar níveis de patch no dispositivo de forma síncrona:
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
}
Verificar se há atualizações do sistema pendentes
Os apps podem avaliar a disponibilidade de atualizações pendentes se comunicando de forma assíncrona com provedores de atualização confiáveis no dispositivo, principalmente atualizações do sistema do Google Play e clientes OTA de OEMs:
fetchAvailableSecurityPatchLevel(): retorna o SPL disponível efetivo para um componente especificado (revertendo para o SPL do dispositivo atual se não houver uma atualização mais recente) que pode ser usado para comparar com o SPL do dispositivo e o SPL publicado.queryAllAvailableUpdates(): descobre todos os provedores de atualização confiáveis no dispositivo e retornaUpdateCheckResultgranular, além de metadados sobre a origem e a atualização dos dados.
Exemplo 1: pedir aos usuários que façam atualizações pendentes
Use fetchAvailableSecurityPatchLevel() para pedir aos usuários que atualizem quando houver atualizações de segurança disponíveis. Por exemplo, ao iniciar 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
Em Java, os métodos assíncronos retornam um ListenableFuture e encaminham
callbacks usando ContextCompat.getMainExecutor():
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));
Exemplo 2: inspecionar o status detalhado do provedor
Use queryAllAvailableUpdates() para inspecionar provedores, carimbos de data/hora e registros de UpdateInfo individuais:
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));
Verificar a resolução de vulnerabilidades e conferir CVEs
Para avaliar mitigações de CVE, verificar a conformidade geral da atualização ou inspecionar os níveis de patch de segurança publicados (PSPLs, na sigla em inglês), seu app precisa primeiro receber e carregar um relatório de vulnerabilidade do OSV, conforme detalhado na referência da API para 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);
Carregar relatórios de vulnerabilidade
- Atualização do WorkManager e do armazenamento em cache local:como os boletins de segurança do Android são publicados mensalmente, armazene em cache o JSON baixado no armazenamento interno (
context.filesDir) e agende uma tarefa periódica em segundo plano comWorkManager(de preferência a cada 24 a 48 horas) para atualizar o relatório, lendo do cache local de forma síncrona na inicialização do app. - Execução em segundo plano:invoque
loadVulnerabilityReport()em uma linha de execução em segundo plano (Dispatchers.IOem Kotlin ou umExecutorem Java) para evitar o bloqueio da linha de execução principal da interface ao analisar registros de CVE. - Avaliação do LTS do kernel:chamar
getPatchedCves(COMPONENT_KERNEL, ...)gera umIllegalArgumentException, eareCvesPatched()não avalia CVEs do kernel. Em vez disso, avalie a segurança do kernel comparando a versão do kernel do dispositivo com as metas de LTS do kernel comum do Android retornadas porgetPublishedSecurityPatchLevel(COMPONENT_KERNEL), correspondendo à ramificação principal e secundária (por exemplo, comparando um kernel5.15.140com a meta5.15.159).
Outros recursos
Para mais informações sobre o estado de segurança do dispositivo, consulte os seguintes recursos:
Documentação
- Boletins de segurança do Android
- Componentes modulares do sistema
- Imagem genérica do kernel (GKI)
- Patches de segurança complementares
- API Play Integrity
- Banco de dados de vulnerabilidades de código aberto (OSV)
- Notas da versão 1.1.0 do Security State