Sichere Zwischenablage

OWASP-Kategorie: MASVS-CODE: Codequalität

Übersicht

Android bietet ein leistungsstarkes Framework, die Zwischenablage, zum Kopieren und Einfügen von Daten zwischen Anwendungen. Bei einer unsachgemäßen Implementierung dieser Funktion können nutzerbezogene Daten für unbefugte böswillige Akteure oder Anwendungen zugänglich gemacht werden.

Das spezifische Risiko, das mit der Offenlegung von Daten in der Zwischenablage verbunden ist, hängt von der Art der Anwendung und den personenbezogenen Daten ab, die sie verarbeitet. Die Auswirkungen sind besonders hoch bei Finanzanwendungen, da sie Zahlungsdaten offenlegen können, oder bei Apps, die Codes für die 2-Faktor-Authentifizierung (2FA) verarbeiten.

Die Angriffsvektoren, die zum Exfiltrieren von Daten aus der Zwischenablage genutzt werden könnten, variieren je nach Android-Version:

  • Bei Android-Versionen vor Android 10 (API-Level 29) können Hintergrund anwendungen auf Informationen aus der Zwischenablage der App im Vordergrund zugreifen. Dadurch können böswillige Akteure möglicherweise direkt auf alle kopierten Daten zugreifen.
  • Ab Android 12 (API-Level 31) wird dem Nutzer jedes Mal, wenn eine Anwendung auf Daten in der Zwischenablage zugreift und sie einfügt, eine Toast-Nachricht angezeigt. Dadurch wird es schwieriger, dass Angriffe unbemerkt bleiben. Zum Schutz personenbezogener Daten unterstützt Android außerdem das spezielle Flag ClipDescription.EXTRA_IS_SENSITIVE oder android.content.extra.IS_SENSITIVE. So können Entwickler die Vorschau des Inhalts der Zwischenablage in der Tastatur-GUI visuell verschleiern und verhindern, dass kopierte Daten im Klartext angezeigt und möglicherweise von böswilligen Anwendungen gestohlen werden. Wenn eines der oben genannten Flags nicht implementiert wird, können Angreifer vertrauliche Daten, die in die Zwischenablage kopiert wurden, möglicherweise durch Shoulder Surfing oder über böswillige Anwendungen exfiltrieren, die im Hintergrund Screenshots erstellen oder Videos der Aktivitäten eines legitimen Nutzers aufzeichnen.

Auswirkungen

Die Ausnutzung einer unsachgemäßen Verarbeitung der Zwischenablage kann dazu führen, dass vertrauliche oder finanzielle Daten von Nutzern von böswilligen Akteuren exfiltriert werden. Dies kann Angreifern helfen, weitere Aktionen wie Phishing-Kampagnen oder Identitätsdiebstahl durchzuführen.

Gegenmaßnahmen

Vorhandensein vertraulicher Daten kennzeichnen

Diese Lösung wird verwendet, um die Vorschau des Inhalts der Zwischenablage in der Tastatur-GUI visuell zu verschleiern. Alle vertraulichen Daten, die kopiert werden können, z. B. Passwörter oder Kreditkartendaten, sollten mit ClipDescription.EXTRA_IS_SENSITIVE oder android.content.extra.IS_SENSITIVE gekennzeichnet werden, bevor ClipboardManager.setPrimaryClip() aufgerufen wird.

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);

Neueste Android-Versionen erzwingen

Wenn die App auf Android-Versionen ab Android 10 (API 29) ausgeführt werden muss, wird verhindert, dass Hintergrundprozesse auf Daten in der Zwischenablage der Vordergrund-App zugreifen.

Wenn die App nur unter Android 10 (API 29) oder höher ausgeführt werden soll, legen Sie die folgenden Werte für die Versionseinstellungen in den Gradle-Build-Dateien in Ihrem Projekt in Android Studio fest.

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"
          ...
      }
      ...
    }
    ...

Inhalte der Zwischenablage nach einem bestimmten Zeitraum löschen

Wenn die Anwendung auf Android-Versionen vor Android 10 (API-Level 29) ausgeführt werden soll, kann jede Hintergrundanwendung auf Daten in der Zwischenablage zugreifen. Um dieses Risiko zu verringern, ist es sinnvoll, eine Funktion zu implementieren, mit der alle Daten, die in die Zwischenablage kopiert wurden, nach einem bestimmten Zeitraum gelöscht werden. Diese Funktion wird ab Android 13 (API-Level 33) automatisch ausgeführt. Bei älteren Android-Versionen kann diese Löschung durchgeführt werden, indem Sie das folgende Snippet in den Code der Anwendung einfügen.

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);

Ressourcen