Kategoria OWASP: MASVS-CODE: jakość kodu
Przegląd
Android oferuje zaawansowany framework, zwany schowkiem, do kopiowania i wklejania danych między aplikacjami. Nieprawidłowe wdrożenie tej funkcji może narazić dane użytkownika na dostęp nieautoryzowanych złośliwych podmiotów lub aplikacji.
Konkretne ryzyko związane z ujawnieniem danych ze schowka zależy od charakteru aplikacji i danych osobowych (PII), które przetwarza. Wpływ jest szczególnie duży w przypadku aplikacji finansowych, ponieważ mogą one ujawniać dane płatności, lub aplikacji, które obsługują kody uwierzytelniania dwuskładnikowego.
Wektory ataków, które można wykorzystać do wyłudzenia danych ze schowka, różnią się w zależności od wersji Androida:
- W wersjach Androida starszych niż Android 10 (poziom interfejsu API 29) aplikacje działające w tle mogą uzyskiwać dostęp do informacji ze schowka aplikacji działającej na pierwszym planie, co może umożliwić złośliwym podmiotom bezpośredni dostęp do skopiowanych danych.
- Od Androida 12 (poziom interfejsu API 31) za każdym razem, gdy aplikacja uzyskuje dostęp do danych w schowku i je wkleja, użytkownikowi wyświetla się komunikat toast, co utrudnia niezauważone przeprowadzenie ataku. Dodatkowo, aby chronić informacje umożliwiające identyfikację, Android obsługuje specjalną flagę
ClipDescription.EXTRA_IS_SENSITIVElubandroid.content.extra.IS_SENSITIVE. Umożliwia ona deweloperom wizualne zaciemnienie podglądu zawartości schowka w interfejsie klawiatury, co uniemożliwia wyświetlanie skopiowanych danych w postaci zwykłego tekstu i potencjalne kradzież przez złośliwe aplikacje. Niezaimplementowanie jednej z wymienionych flag może w rzeczywistości umożliwić atakującym wyłudzenie danych wrażliwych skopiowanych do schowka przez podglądanie ekranu lub za pomocą złośliwych aplikacji, które działając w tle, robią zrzuty ekranu lub nagrywają filmy z aktywności użytkownika.
Wpływ
Wykorzystanie nieprawidłowej obsługi schowka może spowodować wyłudzenie przez złośliwe podmioty danych wrażliwych lub finansowych użytkownika. Może to pomóc atakującym w podejmowaniu dalszych działań, takich jak kampanie phishingowe lub kradzież tożsamości.
Środki zaradcze
Oznaczanie danych wrażliwych
To rozwiązanie służy do wizualnego zaciemniania podglądu zawartości schowka w interfejsie klawiatury. Wszystkie dane wrażliwe, które można skopiować, takie jak
hasła lub dane karty kredytowej, należy oznaczyć flagą
ClipDescription.EXTRA_IS_SENSITIVE lub android.content.extra.IS_SENSITIVE
przed wywołaniem 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);
Wymuszanie najnowszych wersji Androida
Wymuszenie działania aplikacji w wersjach Androida nowszych lub równych Androidowi 10 (interfejs API 29) uniemożliwia procesom działającym w tle dostęp do danych ze schowka w aplikacji działającej na pierwszym planie.
Aby wymusić działanie aplikacji tylko w Androidzie 10 (interfejs API 29) lub nowszym, ustaw te wartości w ustawieniach wersji w plikach kompilacji Gradle w projekcie w Android Studio.
Dynamiczny
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"
...
}
...
}
...
Usuwanie zawartości schowka po określonym czasie
Jeśli aplikacja ma działać w wersjach Androida starszych niż Android 10 (poziom interfejsu API 29), każda aplikacja działająca w tle może uzyskać dostęp do danych ze schowka. Aby zmniejszyć to ryzyko, warto zaimplementować funkcję, która czyści wszystkie dane skopiowane do schowka po określonym czasie. Ta funkcja jest wykonywana automatycznie od Androida 13 (poziom interfejsu API 33). W przypadku starszych wersji Androida to usunięcie można przeprowadzić, dodając ten fragment kodu do kodu aplikacji.
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);
Zasoby
- Framework schowka
- Powiadomienie systemowe wyświetlane, gdy aplikacja uzyskuje dostęp do danych ze schowka
- Dodawanie treści o charakterze kontrowersyjnym do schowka
- Zmiany w zakresie prywatności w Androidzie 10
- Ustawianie informacji o wersji aplikacji