Gestione sicura degli appunti

Categoria OWASP: MASVS-CODE: Qualità del codice

Panoramica

Android offre un potente framework denominato appunti per copiare e incollare dati tra le applicazioni. Un'implementazione non corretta di questa funzionalità potrebbe esporre i dati relativi agli utenti ad attori o applicazioni dannosi non autorizzati.

Il rischio specifico associato all'esposizione dei dati della clipboard dipende dalla natura dell'applicazione e dalle informazioni che consentono l'identificazione personale (PII) che essa gestisce. L'impatto è particolarmente elevato per le applicazioni finanziarie, in quanto potrebbero esporre dati di pagamento o app che gestiscono i codici di autenticazione a due fattori (2FA).

I vettori di attacco che potrebbero essere sfruttati per esfiltrare i dati negli appunti varieranno a seconda della versione di Android:

  • Le versioni di Android precedenti ad Android 10 (livello API 29) consentono alle applicazioni in background di accedere alle informazioni degli appunti delle app in primo piano, potenzialmente consentendo l'accesso diretto a qualsiasi dato copiato da parte di utenti malintenzionati.
  • A partire da Android 12 (livello API 31), ogni volta che un'applicazione accede ai dati all'interno della clipboard e li incolla, all'utente viene mostrato un messaggio popup, il che rende più difficile il passaggio inosservato degli attacchi. Inoltre, per proteggere le PII, Android supporta il flag speciale ClipDescription.EXTRA_IS_SENSITIVE o android.content.extra.IS_SENSITIVE. In questo modo, gli sviluppatori possono nascondere visivamente l'anteprima dei contenuti della clipboard all'interno dell'interfaccia utente della tastiera, impedendo che i dati copiati vengano visualizzati in testo normale e potenzialmente rubati da applicazioni dannose. La mancata implementazione di uno dei flag sopra menzionati potrebbe infatti consentire agli attaccanti di esfiltrare i dati sensibili copiati nella clipboard tramite il furto con sbirciatina o tramite applicazioni dannose che, mentre vengono eseguite in background, acquisiscono screenshot o registrano video delle attività di un utente legittimo.

Impatto

Lo sfruttamento di una gestione impropria degli appunti potrebbe comportare l'esfiltrazione di dati finanziari o sensibili relativi agli utenti da parte di utenti malintenzionati. Ciò potrebbe aiutare gli autori di attacchi a intraprendere ulteriori azioni, come campagne di phishing o furto d'identità.

Mitigazioni

Segnalare dati sensibili

Questa soluzione viene utilizzata per offuscare visivamente l'anteprima dei contenuti della clipboard all'interno della GUI della tastiera. Tutti i dati sensibili che possono essere copiati, ad esempio password o dati di carte di credito, devono essere contrassegnati con ClipDescription.EXTRA_IS_SENSITIVE o android.content.extra.IS_SENSITIVE prima di chiamare ClipboardManager.setPrimaryClip().

Kotlin

// If your app is compiled with the API level 33 SDK or higher.
clipData.apply {
    description.extras = PersistableBundle().apply {
        putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true)
    }
}

// If your app is compiled with API level 32 SDK or lower.
clipData.apply {
    description.extras = PersistableBundle().apply {
        putBoolean("android.content.extra.IS_SENSITIVE", true)
    }
}

Java

// If your app is compiled with the API level 33 SDK or higher.
PersistableBundle extras = new PersistableBundle();
extras.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
clipData.getDescription().setExtras(extras);

// If your app is compiled with API level 32 SDK or lower.
PersistableBundle extras = new PersistableBundle();
extras.putBoolean("android.content.extra.IS_SENSITIVE", true);
clipData.getDescription().setExtras(extras);

Applicare le ultime versioni di Android

L'applicazione dell'obbligo di esecuzione dell'app su versioni di Android successive o uguali ad Android 10 (API 29) impedisce ai processi in background di accedere ai dati degli appunti nell'applicazione in primo piano.

Per imporre l'esecuzione dell'app solo su Android 10 (API 29) o versioni successive, imposta i seguenti valori per le impostazioni di versione nei file di compilazione Gradle all'interno del progetto in Android Studio.

Groovy

android {
      namespace 'com.example.testapp'
      compileSdk [SDK_LATEST_VERSION]

      defaultConfig {
          applicationId "com.example.testapp"
          minSdk 29
          targetSdk [SDK_LATEST_VERSION]
          versionCode 1
          versionName "1.0"
          ...
      }
      ...
    }
    ...

Kotlin

android {
      namespace = "com.example.testapp"
      compileSdk = [SDK_LATEST_VERSION]

      defaultConfig {
          applicationId = "com.example.testapp"
          minSdk = 29
          targetSdk = [SDK_LATEST_VERSION]
          versionCode = 1
          versionName = "1.0"
          ...
      }
      ...
    }
    ...

Eliminare i contenuti degli appunti dopo un determinato periodo di tempo

Se l'applicazione è progettata per funzionare su versioni di Android precedenti ad Android 10 (livello API 29), qualsiasi applicazione in background può accedere ai dati della clipboard. Per ridurre questo rischio, è utile implementare una funzione che cancelli tutti i dati copiati nella clipboard dopo un determinato periodo di tempo. Questa funzione viene eseguito automaticamente a partire da Android 13 (livello API 33). Per le versioni precedenti di Android, questa eliminazione può essere eseguita includendo il seguente snippet nel codice dell'applicazione.

Kotlin

//The Executor makes this task Asynchronous so that the UI continues being responsive
backgroundExecutor.schedule({
    //Creates a clip object with the content of the Clipboard
    val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clip = clipboard.primaryClip
    //If SDK version is higher or equal to 28, it deletes Clipboard data with clearPrimaryClip()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        clipboard.clearPrimaryClip()
    } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
    //If SDK version is lower than 28, it will replace Clipboard content with an empty value
        val newEmptyClip = ClipData.newPlainText("EmptyClipContent", "")
        clipboard.setPrimaryClip(newEmptyClip)
     }
//The delay after which the Clipboard is cleared, measured in seconds
}, 5, TimeUnit.SECONDS)

Java

//The Executor makes this task Asynchronous so that the UI continues being responsive

ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();

backgroundExecutor.schedule(new Runnable() {
    @Override
    public void run() {
        //Creates a clip object with the content of the Clipboard
        ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = clipboard.getPrimaryClip();
        //If SDK version is higher or equal to 28, it deletes Clipboard data with clearPrimaryClip()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            clipboard.clearPrimaryClip();
            //If SDK version is lower than 28, it will replace Clipboard content with an empty value
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            ClipData newEmptyClip = ClipData.newPlainText("EmptyClipContent", "");
            clipboard.setPrimaryClip(newEmptyClip);
        }
    //The delay after which the Clipboard is cleared, measured in seconds
    }, 5, TimeUnit.SECONDS);

Risorse