क्लिपबोर्ड को सुरक्षित तरीके से हैंडल करने की सुविधा

OWASP कैटगरी: MASVS-CODE: कोड की क्वालिटी

खास जानकारी

Android, ऐप्लिकेशन के बीच डेटा को कॉपी और चिपकाने के लिए, क्लिपबोर्ड नाम का एक फ़्रेमवर्क उपलब्ध कराता है. इस सुविधा को गलत तरीके से लागू करने पर, उपयोगकर्ता से जुड़ा डेटा ऐसे लोगों या ऐप्लिकेशन के पास पहुंच सकता है जिनके पास इसे ऐक्सेस करने की अनुमति नहीं है.

क्लिपबोर्ड के डेटा को ऐक्सेस करने से जुड़ा जोखिम, ऐप्लिकेशन के टाइप और उसमें मौजूद व्यक्तिगत पहचान से जुड़ी जानकारी (पीआईआई) पर निर्भर करता है. इसका असर खास तौर पर फ़ाइनेंशियल ऐप्लिकेशन पर पड़ता है. ऐसा इसलिए, क्योंकि ये ऐप्लिकेशन पेमेंट का डेटा दिखा सकते हैं. इसके अलावा, इसका असर उन ऐप्लिकेशन पर भी पड़ता है जो दो चरणों में पुष्टि करने (2FA) के कोड मैनेज करते हैं.

क्लिपबोर्ड से डेटा चुराने के लिए इस्तेमाल किए जा सकने वाले अटैक वेक्टर, Android वर्शन के हिसाब से अलग-अलग होते हैं:

  • Android 10 (एपीआई लेवल 29) से पुराने Android वर्शन में, बैकग्राउंड ऐप्लिकेशन को फ़ोरग्राउंड ऐप्लिकेशन के क्लिपबोर्ड की जानकारी ऐक्सेस करने की अनुमति होती है. इससे नुकसान पहुंचाने वाले लोग, कॉपी किए गए किसी भी डेटा को सीधे तौर पर ऐक्सेस कर सकते हैं.
  • Android 12 (एपीआई लेवल 31) और इसके बाद के वर्शन में, जब भी कोई ऐप्लिकेशन क्लिपबोर्ड में मौजूद डेटा को ऐक्सेस करके चिपकाता है, तो उपयोगकर्ता को एक सूचना दिखती है. इससे हमलों का पता न चल पाना मुश्किल हो जाता है. इसके अलावा, निजी पहचान से जुड़ी जानकारी (पीआईआई) को सुरक्षित रखने के लिए, Android ClipDescription.EXTRA_IS_SENSITIVE या android.content.extra.IS_SENSITIVE स्पेशल फ़्लैग का इस्तेमाल करता है. इससे डेवलपर, कीबोर्ड के जीयूआई में क्लिपबोर्ड के कॉन्टेंट की झलक को छिपा सकते हैं. इससे कॉपी किए गए डेटा को सादे टेक्स्ट में दिखने से रोका जा सकता है. साथ ही, इसे नुकसान पहुंचाने वाले ऐप्लिकेशन से चोरी होने से भी बचाया जा सकता है. ऊपर बताए गए किसी एक फ़्लैग को लागू न करने पर, हमलावर संवेदनशील डेटा को बाहर निकाल सकते हैं. यह डेटा, कंधे के ऊपर से झांककर या ऐसे नुकसान पहुंचाने वाले ऐप्लिकेशन की मदद से क्लिपबोर्ड पर कॉपी किया जाता है जो बैकग्राउंड में चलते समय, असली उपयोगकर्ता की गतिविधियों के स्क्रीनशॉट लेते हैं या वीडियो रिकॉर्ड करते हैं.

असर

क्लिपबोर्ड के गलत इस्तेमाल से, नुकसान पहुंचाने वाले लोग उपयोगकर्ता से जुड़ी संवेदनशील या वित्तीय जानकारी चुरा सकते हैं. इससे हमलावरों को फ़िशिंग कैंपेन या पहचान की चोरी जैसी अन्य कार्रवाइयां करने में मदद मिल सकती है.

जोखिम कम करने के तरीके

संवेदनशील डेटा को फ़्लैग करना

इस समाधान का इस्तेमाल, कीबोर्ड के जीयूआई में क्लिपबोर्ड के कॉन्टेंट की झलक को छिपाने के लिए किया जाता है. पासवर्ड या क्रेडिट कार्ड की जानकारी जैसे किसी भी संवेदनशील डेटा को कॉपी किया जा सकता है. इसलिए, ClipboardManager.setPrimaryClip() को कॉल करने से पहले, ऐसे डेटा को ClipDescription.EXTRA_IS_SENSITIVE या android.content.extra.IS_SENSITIVE के साथ फ़्लैग किया जाना चाहिए.

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

Android के नए वर्शन इस्तेमाल करने की सुविधा चालू करना

ऐप्लिकेशन को Android 10 (API 29) या उसके बाद के वर्शन पर चलाने से, बैकग्राउंड प्रोसेस को फ़ोरग्राउंड ऐप्लिकेशन में क्लिपबोर्ड डेटा ऐक्सेस करने से रोका जा सकता है.

ऐप्लिकेशन को सिर्फ़ Android 10 (एपीआई 29) या इसके बाद के वर्शन पर चलाने के लिए, Android Studio में अपने प्रोजेक्ट की Gradle बिल्ड फ़ाइलों में वर्शन सेटिंग के लिए यहां दी गई वैल्यू सेट करें.

शानदार

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

क्लिपबोर्ड का कॉन्टेंट तय समय के बाद मिटाएं

अगर ऐप्लिकेशन को Android 10 (एपीआई लेवल 29) से पहले के वर्शन पर चलाने के लिए बनाया गया है, तो बैकग्राउंड में चल रहा कोई भी ऐप्लिकेशन, क्लिपबोर्ड के डेटा को ऐक्सेस कर सकता है. इस जोखिम को कम करने के लिए, एक ऐसा फ़ंक्शन लागू करना फ़ायदेमंद होता है जो क्लिपबोर्ड पर कॉपी किए गए किसी भी डेटा को कुछ समय बाद मिटा देता है. यह फ़ंक्शन, Android 13 (एपीआई लेवल 33) से अपने-आप काम करता है. Android के पुराने वर्शन के लिए, ऐप्लिकेशन के कोड में यहां दिया गया स्निपेट शामिल करके, इस कुकी को मिटाया जा सकता है.

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

संसाधन