Web Görünümleri – Güvenli Olmayan URI Yükleme

OWASP kategorisi: MASVS-CODE: Code Quality (MASVS-CODE: Kod Kalitesi)

Genel Bakış

Güvenli olmayan URI yükleme, bir Android uygulaması URI'yi WebView'e yüklemeden önce geçerliliğini doğru şekilde değerlendiremediğinde meydana gelir.

Bu tür güvenlik açığının temel nedeni, URI'nin birden çok bölümden oluşmasıdır.URI'nin bir WebView'e yüklenmesi veya uygulama tarafından dahili olarak kullanılması için en azından şema ve ana makine (yetkili bölümünün) doğrulanması (ör. izin verilenler listesine eklenmesi) gerekir.

En sık yapılan hatalar şunlardır:

  • Şemayı değil ana makineyi kontrol etme. Bu durum, saldırganın kimliği doğrulanmış bir ana makineyle http://, content:// veya javascript:// gibi şemalar kullanmasına olanak tanır.
  • URI'nin özellikle dize olarak alındığı durumlarda doğru şekilde ayrıştırılamaması.
  • Şema doğrulanıyor ancak ana makine doğrulanmıyor (ana makine doğrulaması yetersiz).

Son durumda ise bu durum genellikle uygulamanın birincil alanın rastgele alt alanlarına izin vermesi gerektiğinde ortaya çıkar. Bu nedenle, ana makine adı doğru şekilde ayıklanmış olsa bile uygulama, ayıklanan dize bölümünde birincil alan adının varlığını doğrulamak için startsWith, endsWith, veya contains gibi java.lang.String sınıfı yöntemlerini kullanır. Yanlış kullanıldığında bu yöntemler hatalı sonuçlara yol açabilir ve uygulamanın, kötü amaçlı olabilecek bir ana bilgisayara uygunsuz şekilde güvenmesine neden olabilir.

Etki

Ana makinenin kullanıldığı bağlama bağlı olarak etki değişebilir. Bir WebView'da kötü amaçlı bir URI'nin (ör. filtrelemeyi/izin verilenler listesini atlayan) yüklenmesinin hesap ele geçirmeye (ör. kimlik avı kullanma), kod yürütmeye (ör. kötü amaçlı JavaScript yükleme) veya cihazın güvenliğinin ihlaline (köprü kullanılarak teslim edilen exploit kodu) yol açabileceği durumlarda.

Risk azaltma önlemleri

Dize URI'lerini işlerken dizeyi URI olarak ayrıştırmak ve hem şemayı hem de ana makineyi doğrulamak önemlidir:

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

Ana makine doğrulamasında, ilgili URI bölümü ayrıldıktan sonra ana makinenin güvenilir olup olmadığını doğru bir şekilde belirlemek için bu bölümün tamamen (kısmen değil) doğrulanması önemlidir. startsWith veya endsWith gibi yöntemler kullanmaktan kaçınılamadığında doğru söz dizimini kullanmak ve gerekli karakterleri ya da sembolleri gözden kaçırmamak önemlidir (örneğin, endsWith için doğru eşleşme amacıyla alan adından önce "." nokta karakteri gerekir). Bu karakterlerin göz ardı edilmesi, yanlış eşleşmelere ve güvenlik ihlallerine yol açabilir. Alt alan adları sonsuz sayıda iç içe yerleştirilebildiğinden, normal ifade eşleştirme, ana makine adlarını doğrulamak için önerilen bir strateji değildir.

Katkıda bulunanlar: Microsoft Threat Intelligence'dan Dimitrios Valsamaras ve Michael Peck

Kaynaklar