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

OWASP कैटगरी: MASVS-PLATFORM: Platform Interaction

खास जानकारी

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

नए कॉम्पोनेंट को लॉन्च करने के लिए इस्तेमाल किए गए इंटेंट को कई तरीकों से उपलब्ध कराया जा सकता है. आम तौर पर, इसे 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);

बुनियादी सुरक्षा

Android 16 में, रीडायरेक्शन के फ़ायदों को Intent सुरक्षित करने के लिए, डिफ़ॉल्ट रूप से सुरक्षा को बेहतर बनाने वाला समाधान पेश किया गया है. ज़्यादातर मामलों में, इंटेंट का इस्तेमाल करने वाले ऐप्लिकेशन में, आम तौर पर संगतता से जुड़ी कोई समस्या नहीं आती.

इंटेंट रीडायरेक्शन हैंडलिंग से ऑप्ट आउट करना

Android 16 में एक नया एपीआई पेश किया गया है. इससे ऐप्लिकेशन, लॉन्च सुरक्षा की सुविधाओं से ऑप्ट आउट कर सकते हैं. ऐसा कुछ मामलों में ज़रूरी हो सकता है, जब सुरक्षा से जुड़ी डिफ़ॉल्ट सेटिंग, ऐप्लिकेशन के इस्तेमाल के सही उदाहरणों में रुकावट डालती है.

Android 16 में, सुरक्षा से जुड़ी सुविधाओं से ऑप्ट आउट किया जा सकता है. इसके लिए, Intent ऑब्जेक्ट पर removeLaunchSecurityProtection() तरीके का इस्तेमाल करें. उदाहरण के लिए:

val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }

सामान्य गलतियां

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

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

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

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

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

संसाधन