مدیریت ایمن کلیپ بورد

دسته OWASP: MASVS-CODE: کیفیت کد

نمای کلی

اندروید یک چارچوب قدرتمند به نام کلیپ بورد برای کپی و چسباندن داده ها بین برنامه ها ارائه می دهد. اجرای نادرست این ویژگی می تواند داده های مربوط به کاربر را در معرض عوامل یا برنامه های مخرب غیرمجاز قرار دهد.

خطر خاص مرتبط با قرار گرفتن در معرض داده های کلیپ بورد به ماهیت برنامه و اطلاعات شناسایی شخصی (PII) که در حال رسیدگی است بستگی دارد. این تأثیر به‌ویژه برای برنامه‌های مالی بسیار زیاد است، زیرا ممکن است داده‌های پرداخت یا برنامه‌هایی را که کدهای احراز هویت دو عاملی (2FA) را مدیریت می‌کنند، در معرض دید قرار دهند.

بردارهای حمله ای که می توان از آنها برای استخراج داده های کلیپ بورد استفاده کرد بسته به نسخه اندروید متفاوت است:

  • نسخه‌های Android قدیمی‌تر از Android 10 (سطح API 29) به برنامه‌های پس‌زمینه اجازه می‌دهند به اطلاعات کلیپ‌بورد برنامه پیش‌زمینه دسترسی داشته باشند، و به طور بالقوه امکان دسترسی مستقیم به هر داده کپی شده توسط عوامل مخرب را فراهم می‌کنند.
  • از اندروید 12 به بعد (سطح API 31)، هر بار که یک برنامه به داده‌های درون کلیپ بورد دسترسی پیدا می‌کند و آن‌ها را جای‌گذاری می‌کند، یک پیام نان تست به کاربر نشان داده می‌شود که بی‌توجهی به حملات را دشوارتر می‌کند. علاوه بر این، به منظور محافظت از PII، Android از پرچم ویژه ClipDescription.EXTRA_IS_SENSITIVE یا android.content.extra.IS_SENSITIVE پشتیبانی می کند. این به توسعه‌دهندگان اجازه می‌دهد تا پیش‌نمایش محتوای کلیپ‌بورد را در رابط کاربری گرافیکی صفحه‌کلید مبهم کنند، و از نمایش بصری داده‌های کپی شده در متن واضح و سرقت احتمالی توسط برنامه‌های مخرب جلوگیری می‌کنند. عدم اجرای یکی از پرچم‌های فوق‌الذکر در واقع می‌تواند به مهاجمان اجازه دهد تا داده‌های حساس کپی‌شده در کلیپ‌بورد را از طریق گشت و گذار شانه‌ای یا از طریق برنامه‌های مخربی که در حالی که در پس‌زمینه اجرا می‌شوند، اسکرین شات می‌گیرند یا فیلم‌هایی از فعالیت‌های یک کاربر قانونی ضبط می‌کنند، استخراج کنند.

تاثیر

بهره برداری از مدیریت نادرست کلیپ بورد می تواند منجر به استخراج اطلاعات حساس یا مالی مربوط به کاربر توسط عوامل مخرب شود. این ممکن است به مهاجمان در انجام اقدامات بعدی مانند کمپین های فیشینگ یا سرقت هویت کمک کند.

اقدامات کاهشی

پرچم گذاری داده های حساس

این راه حل برای مبهم کردن بصری پیش نمایش محتوای کلیپ بورد در رابط کاربری گرافیکی صفحه کلید استفاده می شود. قبل از فراخوانی ClipboardManager.setPrimaryClip() ، هرگونه داده حساسی که می‌تواند کپی شود، مانند گذرواژه‌ها یا داده‌های کارت اعتباری، باید با ClipDescription.EXTRA_IS_SENSITIVE یا android.content.extra.IS_SENSITIVE علامت‌گذاری شود.

کاتلین

// 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)
    }
}

جاوا

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

اجرای آخرین نسخه های اندروید

اجرای برنامه در نسخه‌های اندرویدی بعدی یا برابر با Android 10 (API 29) از دسترسی فرآیندهای پس‌زمینه به داده‌های کلیپ‌بورد در برنامه پیش‌زمینه جلوگیری می‌کند.

برای اینکه برنامه فقط در Android 10 (API 29) یا جدیدتر اجرا شود، مقادیر زیر را برای تنظیمات نسخه در فایل‌های ساخت Gradle در پروژه خود در Android Studio تنظیم کنید.

شیار

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

کاتلین

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

محتوای کلیپ بورد را پس از مدت زمان مشخصی حذف کنید

اگر قرار است برنامه روی نسخه‌های اندروید پایین‌تر از Android 10 (سطح API 29) اجرا شود، هر برنامه پس‌زمینه می‌تواند به داده‌های کلیپ‌بورد دسترسی داشته باشد. به منظور کاهش این خطر، پیاده سازی تابعی مفید است که هر داده کپی شده در کلیپ بورد را پس از یک دوره زمانی مشخص پاک می کند. این عملکرد با شروع Android 13 (سطح API 33) به طور خودکار انجام می شود . برای نسخه های قدیمی اندروید، این حذف را می توان با قرار دادن قطعه زیر در کد برنامه انجام داد.

کاتلین

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

جاوا

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

منابع