Controllo dell'accesso basato su autorizzazioni ai componenti esportati

Categoria OWASP: MASVS-PLATFORM: interazione con la piattaforma

Panoramica

Un'autorizzazione Android è un identificatore di stringa dichiarato nel file manifest dell'app per richiedere l'accesso ad azioni o dati con limitazioni, applicato in fase di esecuzione 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
  • Pericolose: autorizzazioni ad alto rischio che potrebbero consentire l'accesso a dati utente sensibili e 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à correlate ai controlli dell'accesso basati sulle autorizzazioni si verificano quando il componente di un'app (ad esempio attività, ricevitore, fornitore di contenuti o servizio) soddisfa tutti i seguenti criteri:

  • Il componente non è associato ad alcun elemento android:permission in Manifest;
  • 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 (a livello di manifest o di codice) delle autorizzazioni.

In questi casi, un'app dannosa può eseguire azioni sensibili abusando dei privilegi del componente vulnerabile, delegando 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 autorizzazioni per attività sensibili

Quando esporti un componente con autorizzazioni sensibili, richiedi le stesse autorizzazioni per qualsiasi richiesta in arrivo. L'IDE Android Studio dispone di controlli di lint per ricipienti e servizi per rilevare questa vulnerabilità e consigliare di richiedere le autorizzazioni appropriate.

Gli sviluppatori possono richiedere le autorizzazioni per le richieste in entrata dichiarandole nel file Manifest oppure 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 componenti con accesso a risorse sensibili, a meno che non sia assolutamente necessario. Puoi farlo impostando android:exported nel Manifest su false per il componente. A partire dal livello API 31 e versioni successive, questo attributo è impostato su false per impostazione predefinita.

Xml

<activity
    android:name=".MyActivity"
    android:exported="false"/>

Applicare autorizzazioni basate su firme

Quando condividi dati tra due app che controlli o possiedi, utilizza le autorizzazioni basate sulle firme. Queste autorizzazioni non richiedono la conferma dell'utente, ma devono controllare che le app che accedono ai dati siano firmate utilizzando la stessa chiave di firma. Questa configurazione offre un'esperienza utente più semplice e sicura. Se dichiari autorizzazioni personalizzate, tieni conto delle 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 con una sola attività

Implementa l'app seguendo il principio di progettazione della separazione delle preoccupazioni. Ogni endpoint deve eseguire solo un piccolo insieme di attività specifiche con privilegi specifici. Questa buona prassi di progettazione consente inoltre allo sviluppatore di applicare autorizzazioni granulari per ogni endpoint. Ad esempio, evita di creare un singolo endpoint che gestisce sia il calendario che i contatti.

Risorse