Sandbox dell'applicazione

La piattaforma Android sfrutta la protezione basata sugli utenti di Linux per identificare e isolare le risorse delle app. In questo modo le app vengono isolate l'una dall'altra e protette, insieme al sistema, dalle app dannose. A questo scopo, Android assegna un ID utente (UID) univoco a ogni app per Android ed esegue ogni app nel proprio processo.

Android utilizza l'UID per configurare una sandbox delle applicazioni a livello di kernel. Il kernel applica la sicurezza tra le app e il sistema a livello di processo tramite funzionalità standard di Linux come gli ID utente e gruppo assegnati alle app. Per impostazione predefinita, le app non possono interagire tra loro e hanno accesso limitato al sistema operativo. Se l'app A tenta di eseguire un'azione dannosa, ad esempio leggere i dati dell'app B o comporre un numero di telefono senza autorizzazione, non può farlo perché non dispone dei privilegi utente predefiniti appropriati. La sandbox è semplice, verificabile e si basa sulla separazione degli utenti di tipo UNIX di processi e autorizzazioni dei file di decenni fa.

Poiché la sandbox delle applicazioni si trova nel kernel, questo modello di sicurezza si estende sia al codice nativo sia alle app del sistema operativo. Tutto il software sopra il kernel, come le librerie del sistema operativo, il framework per app, il runtime delle app e tutte le app, viene eseguito all'interno della sandbox delle applicazioni. Su alcune piattaforme, gli sviluppatori sono vincolati a un framework di sviluppo, a un insieme di API o a un linguaggio specifico. Su Android, non esistono limitazioni relative alla modalità di scrittura di un'app necessarie per applicare la sicurezza. A questo proposito, il codice nativo è sottoposto alla stessa sandbox del codice interpretato.

Protezioni

In genere, per uscire dalla sandbox delle applicazioni in un dispositivo configurato correttamente, è necessario compromettere la sicurezza del kernel di Linux. Tuttavia, come accade per altre funzionalità di sicurezza, le singole protezioni che applicano la sandbox dell'app non sono invulnerabili, pertanto è importante adottare una difesa in profondità per evitare che singole vulnerabilità portino alla compromissione del sistema operativo o di altre app.

Android si basa su una serie di protezioni per applicare la sandbox dell'app. Queste applicazioni sono state introdotte nel tempo e hanno rafforzato notevolmente la sandbox del controllo dell'accesso discrezionale (DAC) basato su UID originale. Le versioni precedenti di Android includevano le seguenti protezioni:

  • In Android 5.0, SELinux forniva il controllo dell'accesso obbligatorio (MAC) tra il sistema e le app. Tuttavia, tutte le app di terze parti venivano eseguite nello stesso contesto SELinux, pertanto l'isolamento tra app veniva applicato principalmente dal controllo dell'accesso con UID.
  • In Android 6.0, la sandbox SELinux è stata estesa per isolare le app al confine per utente fisico. Inoltre, Android ha impostato anche valori predefiniti più sicuri per i dati delle app: per le app con targetSdkVersion >= 24, le autorizzazioni DAC predefinite nella home directory di un'app sono passate da 751 a 700. Questa impostazione predefinita più sicura è stata applicata ai dati delle app private (anche se le app possono sostituire queste impostazioni predefinite).
  • In Android 8.0, tutte le app erano impostate per essere eseguite con un filtro seccomp-bpf che limitava le chiamate di sistema che le app potevano utilizzare, rafforzando così il confine tra app e kernel.
  • In Android 9, tutte le app non privilegiate con targetSdkVersion >= 28 devono essere eseguite in singole sandbox SELinux, fornendo il controllo degli accessi in base all'app. Questa protezione migliora la separazione delle app, impedisce l'override delle impostazioni predefinite sicure e, soprattutto, impedisce alle app di rendere i propri dati accessibili a livello mondiale.
  • In Android 10 le app hanno una visualizzazione non elaborata limitata del filesystem, senza accesso diretto a percorsi come /sdcard/DCIM. Tuttavia, le app mantengono l'accesso completo ai percorsi specifici del pacchetto, come restituito da qualsiasi metodo applicabile, ad esempio Context.getExternalFilesDir().

Linee guida per la condivisione di file

Impostare i dati dell'app come accessibili a tutti non è una buona prassi di sicurezza. L'accesso viene concesso a tutti e non è possibile limitarne l'utilizzo solo ai destinatari previsti. Questa pratica ha portato a fughe di informazioni e a vulnerabilità dei deputati confuse ed è un bersaglio preferito per i malware che hanno come target le app con dati sensibili (come i client di posta elettronica). In Android 9 e versioni successive, la condivisione di file in questo modo non è esplicitamente consentita per le app con targetSdkVersion>=28.

Anziché rendere i dati dell'app accessibili a tutti, segui queste linee guida quando condividi file:

L'autorizzazione di runtime Archiviazione controlla l'accesso alle raccolte fortemente tipizzate tramite MediaStore. Per accedere a file con tipi deboli come i PDF e la classe MediaStore.Downloads, le app devono utilizzare intent come ACTION_OPEN_DOCUMENT.

Per attivare il comportamento di Android 10, utilizza l'attributo requestLegacyExternalStorage manifest e segui le best practice relative alle autorizzazioni app.

  • Il valore predefinito del flag manifest è true per le app destinate ad Android 9 (e versioni precedenti).
  • Il valore predefinito è false per le app destinate ad Android 10. Per disattivare temporaneamente la visualizzazione dello spazio di archiviazione filtrato nelle app destinate ad Android 10, imposta il valore del flag manifest su true.
  • Utilizzando le autorizzazioni con restrizioni, il programma di installazione inserisce nella lista consentita le app consentite per lo spazio di archiviazione non in sandbox. Le app non incluse nella lista consentita sono messe in sandbox.