Categoria OWASP: MASVS-PLATFORM: Platform Interaction
Panoramica
Un'autorizzazione Android è un identificatore di stringa dichiarato nel manifest dell'app per richiedere l'accesso a dati o azioni con limitazioni, applicato in fase di runtime dal framework Android.
I livelli di autorizzazione Android indicano il potenziale rischio associato all' autorizzazione:
- Normale: autorizzazioni a basso rischio, concesse automaticamente al momento dell'installazione
- Pericolosa: autorizzazioni ad alto rischio che potrebbero consentire l'accesso a dati utente sensibili, che richiedono l'approvazione esplicita dell'utente in fase di runtime
- Firma: concessa solo alle app firmate con lo stesso certificato dell' app che dichiara l'autorizzazione, in genere utilizzata per le app di sistema o le interazioni tra app dello stesso sviluppatore
Le vulnerabilità relative ai controlli di accesso basati sulle autorizzazioni si verificano quando un componente di un'app (ad esempio attività, ricevitore, content provider o servizio) soddisfa tutti i seguenti criteri:
- Il componente non è associato ad alcun
android:permissionnelManifest; - Il componente esegue un'attività sensibile per la quale esiste un'autorizzazione che l'utente ha già approvato;
- Il componente viene esportato;
- Il componente non esegue controlli manuali delle autorizzazioni (a livello di manifest o di codice);
In questo caso, un'app dannosa può eseguire azioni sensibili abusando dei privilegi del componente vulnerabile, trasferendo i privilegi dell'app vulnerabile all'app dannosa.
Impatto
L'esportazione di componenti vulnerabili può essere utilizzata per ottenere l'accesso a risorse sensibili o per eseguire azioni sensibili. L'impatto di questo comportamento indesiderato dipende dal contesto del componente vulnerabile e dai relativi privilegi.
Mitigazioni
Richiedere le autorizzazioni per le attività sensibili
Quando esporti un componente con autorizzazioni sensibili, richiedi le stesse autorizzazioni per qualsiasi richiesta in entrata. L'IDE Android Studio dispone di controlli lint per ricevitori e servizi per individuare questa vulnerabilità e consigliare di richiedere le autorizzazioni appropriate.
Gli sviluppatori possono richiedere le autorizzazioni per le richieste in entrata dichiarandole nel file Manifest o a livello di codice durante l'implementazione del servizio, come negli esempi seguenti.
Xml
<manifest ...>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application ...>
<service android:name=".MyExportService"
android:exported="true"
android:permission="android.permission.READ_CONTACTS" />
</application>
</manifest>
Kotlin
class MyExportService : Service() {
private val binder = MyExportBinder()
override fun onBind(intent: Intent): IBinder? {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
// Permission is enforced, proceed with export logic
return binder
}
// Inner class for your Binder implementation
private inner class MyExportBinder : Binder() {
// Permission is enforced, proceed with export logic
}
}
Java
public class MyExportService extends Service {
@Override
public IBinder onBind(Intent intent) {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");
return binder;
}
// Inner class for your Binder implementation
private class MyExportBinder extends Binder {
// Permission is enforced, proceed with export logic
}
}
Non esportare il componente
Evita di esportare i componenti con accesso a risorse sensibili, a meno che non sia assolutamente necessario. Puoi farlo impostando android:exported nel file Manifest su false per il componente. A partire dal livello API 31 e
oltre, questo attributo è impostato su false per impostazione predefinita.
Xml
<activity
android:name=".MyActivity"
android:exported="false"/>
Applicare le autorizzazioni basate sulla firma
Quando condividi dati tra due app che controlli o di cui sei proprietario, utilizza le autorizzazioni basate sulla firma. Queste autorizzazioni non richiedono la conferma dell'utente e, invece, verificano che le app che accedono ai dati siano firmate utilizzando la stessa chiave di firma. Questa configurazione offre un'esperienza utente più semplificata e sicura. Se dichiari autorizzazioni personalizzate, tieni in considerazione le linee guida per la sicurezza corrispondenti.
Xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<permission android:name="my_custom_permission_name"
android:protectionLevel="signature" />
Endpoint a singola attività
Implementa l'app seguendo il principio di progettazione della separazione delle responsabilità. Ogni endpoint deve eseguire solo un piccolo insieme di attività specifiche con privilegi specifici. Questa buona pratica di progettazione consente inoltre allo sviluppatore di applicare autorizzazioni granulari per ogni endpoint. Ad esempio, evita di creare un singolo endpoint che gestisca sia il calendario sia i contatti.
Risorse
- Android Access to app protected components from the Oversecured blog
- Best practice per i content provider
- Autorizzazioni di runtime (pericolose)
- Principio di progettazione della separazione delle responsabilità
- Documentazione sulle autorizzazioni Android
- Suggerimenti per la sicurezza dei ricevitori di trasmissione Android
- Suggerimenti per la sicurezza dei servizi Android
- Android 12 (API 31) exported default set to "false"
- Lint Check: Exported PreferenceActivity shouldn't be exported
- Lint Check: Exported Receiver doesn't require permission
- Lint Check: Exported Service doesn't require permission