Panolara Güvenli Kullanım

OWASP kategorisi: MASVS-CODE: Kod Kalitesi

Genel Bakış

Android, uygulamalar arasında veri kopyalama ve yapıştırma için pano olarak adlandırılan güçlü bir çerçeve sunar. Bu özelliğin yanlış uygulanması, kullanıcıyla ilgili verileri yetkisiz kötü amaçlı kişilere veya uygulamalara açabilir.

Araç panosundaki verilerin ifşa edilmesiyle ilişkili risk, uygulamanın yapısına ve işlediği kimliği tanımlayabilecek bilgilere (PII) bağlıdır. Bu durum, ödeme verilerini açığa çıkarabilecekleri veya iki faktörlü kimlik doğrulama (2FA) kodlarını işleyen uygulamalar olduğu için özellikle finansal uygulamalar için büyük önem taşır.

Panoya kopyalanan verileri sızdırmak için kullanılabilecek saldırı vektörleri Android sürümüne göre değişiklik gösterir:

  • Android 10'dan (API düzeyi 29) eski Android sürümleri, arka plan uygulamalarının ön plan uygulama panosundaki bilgilere erişmesine izin verir. Bu da, kopyalanan verilere kötü amaçlı kişiler tarafından doğrudan erişilmesine olanak tanıyabilir.
  • Android 12'den (API düzeyi 31) itibaren, bir uygulama panoya erişip verileri her yapıştırdığında kullanıcıya bir pop-up mesaj gösterilir. Bu sayede, saldırıların fark edilmemesi daha zor olur. Ayrıca Android, kimliği tanımlayabilecek bilgileri korumak için ClipDescription.EXTRA_IS_SENSITIVE veya android.content.extra.IS_SENSITIVE özel işaretini destekler. Bu sayede geliştiriciler, kopyalanan verilerin görsel olarak açık metin olarak gösterilmesini ve kötü amaçlı uygulamalar tarafından çalınmasını önleyerek klavye kullanıcı arayüzündeki panosundaki içerik önizlemesini görsel olarak karartabilir. Yukarıda belirtilen işaretlerden birini uygulamamak, saldırganların arka planda çalışırken meşru bir kullanıcının etkinliklerinin ekran görüntülerini alan veya videolarını kaydeden kötü amaçlı uygulamalar aracılığıyla ya da omuz izleyerek, panosuna kopyalanan hassas verileri sızdırmasına neden olabilir.

Etki

Yanlış şekilde kullanılan panosunun kötüye kullanılması, kullanıcıyla ilgili hassas veya finansal verilerin kötü amaçlı kişiler tarafından çalınmasına neden olabilir. Bu, saldırganların kimlik avı kampanyaları veya kimlik hırsızlığı gibi başka işlemler gerçekleştirmesine yardımcı olabilir.

Çözümler

Hassas Verileri İşaretleme

Bu çözüm, klavye kullanıcı arayüzündeki panosundaki içerik önizlemesini görsel olarak gizlemek için kullanılır. Şifre veya kredi kartı verileri gibi kopyalanabilen hassas veriler, ClipboardManager.setPrimaryClip() numaralı telefonu aramadan önce ClipDescription.EXTRA_IS_SENSITIVE veya android.content.extra.IS_SENSITIVE ile işaretlenmelidir.

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

En son Android sürümlerini zorunlu kılma

Uygulamanın Android 10 veya sonraki sürümlerde (API 29) çalışmasını zorunlu kılmak, arka plan işlemlerinin ön plan uygulamasındaki pano verilerine erişmesini engeller.

Uygulamanın yalnızca Android 10 (API 29) veya sonraki sürümlerde çalışmasını zorunlu kılmak için Android Studio'daki projenizdeki Gradle derleme dosyalarında sürüm ayarları için aşağıdaki değerleri ayarlayın.

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

Belirli bir süre sonra pano içeriğini silme

Uygulamanın Android 10'dan (API düzeyi 29) daha düşük Android sürümlerinde çalıştırılması amaçlanıyorsa tüm arka plan uygulamaları, panos verilerine erişebilir. Bu riski azaltmak için, belirli bir süre geçtikten sonra panoya kopyalanan tüm verileri temizleyen bir işlev uygulamak faydalıdır. Bu işlev, Android 13'ten (API düzeyi 33) itibaren otomatik olarak gerçekleştirilir. Eski Android sürümlerinde bu silme işlemi, uygulamanın koduna aşağıdaki snippet'in eklenmesi ile yapılabilir.

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

Kaynaklar