OWASP कैटगरी: MASVS-CODE: कोड की क्वालिटी
खास जानकारी
असुरक्षित यूआरआई लोडिंग तब होती है, जब कोई Android ऐप्लिकेशन किसी यूआरआई को WebView में लोड करने से पहले, उसकी वैधता का सही तरीके से आकलन नहीं कर पाता.
इस तरह की कमज़ोरी की मुख्य वजह यह है कि यूआरआई में कई हिस्से होते हैं.इनमें से कम से कम स्कीम और होस्ट (अथॉरिटी वाले हिस्से का) की पुष्टि होनी चाहिए. जैसे, यूआरआई को WebView में लोड करने या ऐप्लिकेशन में इसका इस्तेमाल करने से पहले, इसे अनुमति वाली सूची में शामिल किया जाना चाहिए.
आम तौर पर होने वाली गलतियां:
- इसमें सिर्फ़ होस्ट की जांच की जाती है, न कि स्कीम की. इससे हमलावर, पुष्टि किए गए होस्ट के साथ
http://
,content://
याjavascript://
जैसी स्कीम का इस्तेमाल कर सकता है. - यूआरआई को सही तरीके से पार्स न कर पाना. खास तौर पर, उन मामलों में जहां यूआरआई को स्ट्रिंग के तौर पर भेजा जाता है.
- स्कीम की पुष्टि की जा रही है, लेकिन होस्ट की नहीं (होस्ट की पुष्टि नहीं हो रही है).
आखिरी मामले में, ऐसा आम तौर पर तब होता है, जब ऐप्लिकेशन को किसी प्राइमरी डोमेन के किसी भी सबडोमेन को अनुमति देनी होती है. इसलिए, भले ही होस्टनेम को सही तरीके से निकाला गया हो, ऐप्लिकेशन, निकाले गए स्ट्रिंग सेक्शन में प्राइमरी डोमेन की मौजूदगी की पुष्टि करने के लिए, java.lang.String
क्लास के startsWith
, endsWith,
या contains
जैसे तरीकों का इस्तेमाल करता है. इन तरीकों का गलत इस्तेमाल करने से, गलत नतीजे मिल सकते हैं. साथ ही, ऐप्लिकेशन को ऐसे होस्ट पर भरोसा करने के लिए मजबूर किया जा सकता है जो नुकसान पहुंचा सकता है.
असर
होस्ट का इस्तेमाल किस संदर्भ में किया जा रहा है, इसके आधार पर असर अलग-अलग हो सकता है. ऐसे मामलों में जहां वेबव्यू में नुकसान पहुंचाने वाला यूआरआई लोड करने से, खाता हैक किया जा सकता है. जैसे, फ़िशिंग का इस्तेमाल करना. इसके अलावा, कोड लागू किया जा सकता है. जैसे, नुकसान पहुंचाने वाली JavaScript लोड करना. साथ ही, डिवाइस से समझौता किया जा सकता है. जैसे, हाइपरलिंक का इस्तेमाल करके डिलीवर किए गए कोड का गलत इस्तेमाल करना.
जोखिम कम करने के तरीके
स्ट्रिंग यूआरआई को हैंडल करते समय, स्ट्रिंग को यूआरआई के तौर पर पार्स करना ज़रूरी है. साथ ही, स्कीम और होस्ट, दोनों की पुष्टि करना भी ज़रूरी है:
Kotlin
fun isUriTrusted(incomingUri: String, trustedHostName: String): Boolean {
try {
val uri = Uri.parse(incomingUri)
return uri.scheme == "https" && uri.host == trustedHostName
} catch (e: NullPointerException) {
throw NullPointerException("incomingUri is null or not well-formed")
}
}
Java
public static boolean isUriTrusted(String incomingUri, String trustedHostName)
throws NullPointerException {
try {
Uri uri = Uri.parse(incomingUri);
return uri.getScheme().equals("https") &&
uri.getHost().equals(trustedHostName);
} catch (NullPointerException e) {
throw new NullPointerException(
"incomingUri is null or not well-formed");
}
}
होस्ट की पुष्टि करने के लिए, यूआरआई के उस हिस्से को अलग करने के बाद, यह ज़रूरी है कि उसकी पूरी तरह से पुष्टि की जाए. ऐसा इसलिए, ताकि यह पता लगाया जा सके कि होस्ट भरोसेमंद है या नहीं. अगर startsWith
या endsWith
जैसे तरीकों का इस्तेमाल करना ज़रूरी हो, तो सही सिंटैक्स का इस्तेमाल करना ज़रूरी है. साथ ही, ज़रूरी वर्णों या सिंबल को अनदेखा नहीं करना चाहिए. उदाहरण के लिए, सटीक मिलान के लिए endsWith
को डोमेन नाम से पहले ".
" डॉट वर्ण की ज़रूरत होती है. इन वर्णों को अनदेखा करने से, गलत मिलान हो सकते हैं और सुरक्षा से समझौता हो सकता है. सबडोमेन को कई बार नेस्ट किया जा सकता है. इसलिए, होस्टनेम की पुष्टि करने के लिए, रेगुलर एक्सप्रेशन मैचिंग का इस्तेमाल करने का सुझाव नहीं दिया जाता.
योगदान देने वाले लोग: Microsoft Threat Intelligence के दिमित्रियोस वाल्समारस और माइकल पेक