इंटेंट रीडायरेक्शन

OWASP कैटगरी: MASVS-PLATFORM: प्लैटफ़ॉर्म इंटरैक्शन

खास जानकारी

इंटेंट रीडायरेक्शन तब होता है, जब कोई हमलावर किसी ऐप्लिकेशन के संदर्भ में, नए कॉम्पोनेंट को लॉन्च करने के लिए इस्तेमाल किए गए इंटेंट के कॉन्टेंट को कुछ हद तक या पूरी तरह से कंट्रोल कर सकता है.

नए कॉम्पोनेंट को लॉन्च करने के लिए इस्तेमाल किए गए इंटेंट को कई तरीकों से दिया जा सकता है. आम तौर पर, इसे extras फ़ील्ड में सीरियलाइज़ किए गए इंटेंट के तौर पर या स्ट्रिंग में मार्शल करके पार्स किया जाता है. पैरामीटर को कुछ हद तक कंट्रोल करने से भी यही नतीजा मिल सकता है.

असर

इसकी वजह से, अलग-अलग तरह का असर पड़ सकता है. हमलावर, असुरक्षित ऐप्लिकेशन में मौजूद इंटरनल सुविधाओं को चालू कर सकता है. इसके अलावा, वह एक्सपोर्ट नहीं किए गए ContentProvider ऑब्जेक्ट जैसे निजी कॉम्पोनेंट को ऐक्सेस कर सकता है.

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

आम तौर पर, नेस्ट किए गए इंटेंट को रीडायरेक्ट करने से जुड़ी सुविधाओं को एक्सपोज़ न करें. अगर ऐसा करना ज़रूरी हो, तो इन तरीकों का इस्तेमाल करके, डेटा को सुरक्षित रखें:

  • बंडल की गई जानकारी को सही तरीके से साफ़ करें. यह ज़रूरी है कि आप फ़्लैग (FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION) की जांच करें या उन्हें हटाएं. साथ ही, यह भी देखें कि इंटेंट को कहां रीडायरेक्ट किया जा रहा है. IntentSanitizer इस प्रोसेस में आपकी मदद कर सकता है.
  • PendingIntent ऑब्जेक्ट का इस्तेमाल करें. इससे आपके कॉम्पोनेंट को एक्सपोर्ट नहीं किया जा सकता और टारगेट कार्रवाई के इंटेंट में बदलाव नहीं किया जा सकता.

ऐप्लिकेशन यह देख सकते हैं कि किसी इंटेंट को कहां रीडायरेक्ट किया जा रहा है. इसके लिए, वे ResolveActivity जैसे तरीकों का इस्तेमाल कर सकते हैं:

Kotlin

val intent = getIntent()
// Get the component name of the nested intent.
val forward = intent.getParcelableExtra<Parcelable>("key") as Intent
val name: ComponentName = forward.resolveActivity(packageManager)
// Check that the package name and class name contain the expected values.
if (name.packagename == "safe_package" && name.className == "safe_class") {
    // Redirect the nested intent.
    startActivity(forward)
}

Java

Intent intent = getIntent()
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
        name.getClassName().equals("safe_class")) {
    // Redirect the nested intent.
    startActivity(forward);
}

ऐप्लिकेशन, IntentSanitizer का इस्तेमाल, यहां दिए गए लॉजिक के मुताबिक कर सकते हैं:

Kotlin

val intent = IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent)

Java

Intent intent = new  IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent);

आम तौर पर होने वाली गलतियां

  • जांच की जा रही है कि getCallingActivity() शून्य के अलावा कोई वैल्यू दिखाता है या नहीं. इस फ़ंक्शन के लिए, नुकसान पहुंचाने वाले ऐप्लिकेशन, शून्य वैल्यू दे सकते हैं.
  • यह मानते हुए कि checkCallingPermission() सभी संदर्भों में काम करता है या असल में पूर्णांक दिखाने पर, तरीका कोई अपवाद दिखाता है.

डीबग करने की सुविधाएं

Android 12 (एपीआई लेवल 31) या उसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन के लिए, डीबग करने की सुविधा चालू की जा सकती है. इससे, कुछ मामलों में यह पता चलता है कि आपका ऐप्लिकेशन किसी इंटेंट को असुरक्षित तरीके से लॉन्च कर रहा है या नहीं.

अगर आपका ऐप्लिकेशन नीचे दी गई दोनों कार्रवाइयां करता है, तो सिस्टम असुरक्षित इंटेंट लॉन्च का पता लगाता है और StrictMode का उल्लंघन करता है:

  • आपका ऐप्लिकेशन, डिलीवर किए गए इंटेंट के एक्सट्रा से नेस्ट किए गए इंटेंट को अनपैक करता है.
  • आपका ऐप्लिकेशन, नेस्ट किए गए उस इंटेंट का इस्तेमाल करके तुरंत ऐप्लिकेशन कॉम्पोनेंट शुरू कर देता है. जैसे, इंटेंट को startActivity(), startService() या bindService() में पास करना.

संसाधन