Questo documento descrive come gli sviluppatori di app possono utilizzare le funzionalità di sicurezza fornite da Android per definire le proprie autorizzazioni. Definendo autorizzazioni personalizzate, un'app può condividere le proprie risorse e funzionalità con altre app. Per ulteriori informazioni sulle autorizzazioni, consulta la panoramica delle autorizzazioni.
Sfondo
Android è un sistema operativo con separazione dei privilegi, in cui ogni app viene eseguita con un'identità di sistema distinta (ID utente e ID gruppo Linux). Anche le parti del sistema sono separate in identità distinte. In questo modo, Linux isola le app tra loro e dal sistema.
Le app possono esporre le proprie funzionalità ad altre app definendo le autorizzazioni che altre app possono richiedere. Possono anche definire autorizzazioni che vengono rese disponibili automaticamente a qualsiasi altra app firmata con lo stesso certificato.
Firma dell'app
Tutti gli APK devono essere firmati con un certificato la cui chiave privata è detenuta dallo sviluppatore. Il certificato non deve essere firmato da un'autorità di certificazione. È consentito e tipico che le app per Android utilizzino certificati autofirmati. Lo scopo dei certificati in Android è distinguere gli autori delle app. In questo modo il sistema può concedere o negare alle app l'accesso alle autorizzazioni a livello di firma e concedere o negare a un'app la richiesta di ricevere la stessa identità Linux di un'altra app.
Concedere le autorizzazioni di firma dopo il tempo di produzione del dispositivo
A partire da Android 12 (livello API 31), l'attributo
knownCerts
per le autorizzazioni a livello di firma consente di fare riferimento ai digest di certificati di firma noti al momento della dichiarazione.
Puoi dichiarare l'attributo knownCerts
e utilizzare il flag knownSigner
nell'attributo protectionLevel
della tua app
per una determinata autorizzazione a livello di firma. Il sistema
concede l'autorizzazione a un'app richiedente se uno dei firmatari nella
genealogia di firma dell'app richiedente, incluso il firmatario attuale, corrisponde a uno dei digest
dichiarati con l'autorizzazione nell'attributo knownCerts
.
Il flag knownSigner
consente a dispositivi e app di concedere autorizzazioni di firma ad
altre app senza doverle firmare al momento della produzione
e della spedizione del dispositivo.
ID utente e accesso ai file
Al momento dell'installazione, Android assegna a ogni pacchetto un ID utente Linux distinto. L'identità rimane costante per tutta la durata del pacchetto sul dispositivo. Su un altro dispositivo, lo stesso pacchetto potrebbe avere un UID diverso. Ciò che conta è che ogni pacchetto abbia un UID distinto su un determinato dispositivo.
Poiché l'applicazione della sicurezza avviene a livello di processo, il codice di due pacchetti non può normalmente essere eseguito nello stesso processo, in quanto deve essere eseguito come utenti Linux diversi.
A tutti i dati archiviati da un'app viene assegnato l'ID utente dell'app e normalmente non sono accessibili ad altri pacchetti.
Per ulteriori informazioni sul modello di sicurezza di Android, consulta la panoramica sulla sicurezza di Android.
Definire e applicare le autorizzazioni
Per applicare le tue autorizzazioni, devi prima dichiararle nel tuo
AndroidManifest.xml
utilizzando uno o più elementi
<permission>
.
Convenzione di denominazione
Il sistema non consente a più pacchetti di dichiarare un'autorizzazione con lo stesso nome, a meno che tutti i pacchetti non siano firmati con lo stesso certificato. Se un pacchetto dichiara un'autorizzazione, il sistema non consente all'utente di installare altri pacchetti con lo stesso nome di autorizzazione, a meno che questi pacchetti non siano firmati con lo stesso certificato del primo pacchetto.
Ti consigliamo di aggiungere un prefisso alle autorizzazioni con il nome del pacchetto di un'app, utilizzando
una denominazione in stile dominio inverso, seguita da .permission.
e poi da una descrizione della funzionalità rappresentata dall'autorizzazione, in
SNAKE_CASE maiuscolo. Ad esempio,
com.example.myapp.permission.ENGAGE_HYPERSPACE
.
Seguendo questo consiglio, si evitano conflitti di denominazione e si identifica chiaramente il proprietario e l'intenzione di un'autorizzazione personalizzata.
Esempio
Ad esempio, un'app che deve controllare quali altre app possono avviare una delle sue attività può dichiarare un'autorizzazione per questa operazione nel seguente modo:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous" /> ... </manifest>
L'attributo
protectionLevel
è obbligatorio e indica al sistema come
informare gli utenti delle app che richiedono l'autorizzazione o quali app possono
detenere l'autorizzazione, come descritto nella documentazione collegata.
L'attributo android:permissionGroup
è facoltativo e viene utilizzato solo per aiutare il sistema a mostrare le autorizzazioni
all'utente. Nella maggior parte dei casi, questo valore viene impostato su un gruppo di sistema standard (elencato in android.Manifest.permission_group
), anche se puoi definire un gruppo autonomamente, come descritto nella sezione seguente.
Ti consigliamo di utilizzare un gruppo esistente, perché semplifica l'interfaccia utente delle autorizzazioni mostrata all'utente.
Devi fornire sia un'etichetta che una descrizione per l'autorizzazione. Si tratta di risorse stringa che l'utente può visualizzare quando
visualizza un elenco di autorizzazioni
(android:label
)
o i dettagli di una singola autorizzazione
(android:description
).
L'etichetta è breve: poche parole che descrivono la funzionalità
chiave che l'autorizzazione protegge. La descrizione è
un paio di frasi che descrivono cosa consente di fare l'autorizzazione a un titolare. La nostra
convenzione prevede una descrizione di due frasi, in cui la prima descrive
l'autorizzazione e la seconda avvisa l'utente del tipo di cose
che possono andare storte se a un'app viene concessa l'autorizzazione.
Ecco un esempio di etichetta e descrizione per l'autorizzazione
CALL_PHONE
:
<string name="permlab_callPhone">directly call phone numbers</string> <string name="permdesc_callPhone">Allows the app to call non-emergency phone numbers without your intervention. Malicious apps may cause unexpected calls on your phone bill.</string>
Creare un gruppo di autorizzazioni
Come mostrato nella sezione precedente, puoi utilizzare l'attributo
android:permissionGroup
per aiutare il sistema a descrivere
le autorizzazioni all'utente. Nella maggior parte dei casi, questo valore viene impostato su un gruppo di sistema standard (elencato in android.Manifest.permission_group
), ma puoi anche definire il tuo gruppo con <permission-group>
.
L'elemento <permission-group>
definisce un'etichetta per un insieme
di autorizzazioni, sia quelle dichiarate nel manifest con gli elementi
<permission>
sia quelle dichiarate altrove. Ciò influisce solo sul modo in cui le autorizzazioni
vengono raggruppate quando vengono presentate all'utente. L'elemento
<permission-group>
non specifica le autorizzazioni che appartengono al gruppo, ma
gli assegna un nome.
Puoi inserire un'autorizzazione nel gruppo assegnando il nome del gruppo all'attributo
<permission>
dell'elemento
permissionGroup
.
L'elemento
<permission-tree>
dichiara uno spazio dei nomi per un gruppo di autorizzazioni definite nel
codice.
Suggerimenti per le autorizzazioni personalizzate
Puoi definire autorizzazioni personalizzate per le tue app e richiedere autorizzazioni personalizzate
da altre app definendo elementi <uses-permission>
.
Tuttavia, valuta attentamente se è necessario farlo.
- Se stai progettando una suite di app che espongono funzionalità l'una all'altra, cerca di progettare le app in modo che ogni autorizzazione venga definita una sola volta. Devi farlo se le app non sono tutte firmate con lo stesso certificato. Anche se tutte le app sono firmate con lo stesso certificato, la best practice prevede di definire ogni autorizzazione una sola volta.
- Se la funzionalità è disponibile solo per le app firmate con la stessa firma dell'app che la fornisce, potresti evitare di definire autorizzazioni personalizzate utilizzando i controlli della firma. Quando una delle tue app effettua una richiesta a un'altra delle tue app, la seconda app può verificare che entrambe le app siano firmate con lo stesso certificato prima di soddisfare la richiesta.
Se è necessaria un'autorizzazione personalizzata, valuta se solo le applicazioni firmate dallo stesso sviluppatore dell'applicazione che esegue il controllo dell'autorizzazione devono accedervi, ad esempio quando implementi comunicazioni interprocesso sicure tra due applicazioni dello stesso sviluppatore. In questo caso, ti consigliamo di utilizzare le autorizzazioni della firma. Le autorizzazioni della firma sono trasparenti per l'utente ed evitano le autorizzazioni confermate dall'utente, che possono confondere gli utenti.
Continua a leggere per scoprire di più su:
<uses-permission>
- Riferimento API per il tag manifest che dichiara le autorizzazioni di sistema richieste dalla tua app.
Potrebbe interessarti anche:
- Panoramica sulla sicurezza di Android
- Una discussione dettagliata sul modello di sicurezza della piattaforma Android.