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

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 (एपीआई 29) या उसके बाद के वर्शन पर चलाने से, बैकग्राउंड प्रोसेस को फ़ोरग्राउंड ऐप्लिकेशन में क्लिपबोर्ड का डेटा ऐक्सेस करने से रोका जा सकता है.

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

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

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

अगर ऐप्लिकेशन को 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);

संसाधन