OWASP kategorisi: MASVS-PLATFORM: Platform Etkileşimi
Genel Bakış
Bazen JavaScript köprüsü olarak da bilinen yerel köprü, addJavascriptInterface yöntemi kullanılarak WebView ile yerel Android kodu arasındaki iletişimi kolaylaştıran bir mekanizmadır. Bu, WebView'da çalışan JavaScript kodu ile Android uygulamasının Java kodu arasında iki yönlü iletişime olanak tanır. addJavascriptInterface yöntemi, bir Java nesnesini WebView'ın tüm çerçevelerine sunar. Herhangi bir çerçeve, nesne adına erişebilir ve üzerinde yöntemler çağırabilir. Ancak uygulamanın, WebView'daki arayan çerçevenin kaynağını doğrulayabileceği bir mekanizma yoktur. Bu durum, içeriğin güvenilirliği belirsiz kaldığı için güvenlik endişelerine yol açar.
Yerel köprü, JavaScript Window.postMessage ile iletişim kurmak için Android'in WebViewCompat.postWebMessage veya WebMessagePort.postMessage kullanılarak HTML mesaj kanallarıyla da uygulanabilir. WebViewCompat.postWebMessage ve
WebMessagePort.postMessage, Window.postMessage üzerinden gönderilen ve WebView içinde yürütülecek JavaScript mesajlarını kabul edebilir.
Yerel köprülerle ilişkili birden fazla risk vardır:
- JavascriptInterface tabanlı köprüler:
addJavascriptInterfaceyöntemi, sağlanan bir Java nesnesini iframe'ler de dahil olmak üzere WebView'ın her çerçevesine yerleştirir. Bu nedenle, çerçeveleri meşru bir web sitesine yerleştiren kötü amaçlı üçüncü tarafların saldırısına karşı savunmasızdır. API düzeyi 16 veya önceki sürümleri hedefleyen uygulamalar, özellikle saldırı riski altındadır. Çünkü bu yöntem, JavaScript'in ana makine uygulamasını kontrol etmesine izin vermek için kullanılabilir.- Yerel köprü etkinleştirilmiş WebView'larda güvenilmeyen kullanıcı tarafından sağlanan içeriğin yansıtılması, siteler arası komut dosyası çalıştırma (XSS) saldırılarına olanak tanır.
- MessageChannel tabanlı köprüler:
- İleti kanalı uç noktalarında kaynak kontrollerinin olmaması, kötü amaçlı kod içerenler de dahil olmak üzere tüm gönderenlerden gelen iletilerin kabul edileceği anlamına gelir.
- Java'yı yanlışlıkla rastgele JavaScript'e maruz bırakmak mümkündür.
Etki
addJavascriptInterface, postWebMessage ve postMessage yöntemleri, kötü niyetli kişiler tarafından kontrol ettikleri koda erişmek, bu kodu değiştirmek veya bir WebView'a yerleştirmek için kullanılabilir. Bu durum, kullanıcıların kötü amaçlı sitelere yönlendirilmesine, kötü amaçlı içeriklerin yüklenmesine veya cihazlarında hassas verileri ayıklayabilen ya da ayrıcalık artırma elde edebilen kötü amaçlı kodların çalıştırılmasına neden olabilir.
Risk: addJavascriptInterface riskleri
WebView, sayfa oluşturma, gezinme ve JavaScript'i yürütme gibi temel tarayıcı işlevlerini uygular. WebView, bir etkinlik düzeninin parçası olarak web içeriğini görüntülemek için uygulama içinde kullanılabilir. addJavascriptInterface yöntemi kullanılarak bir WebView'da yerel köprü uygulanması, siteler arası komut dosyası çalıştırma (XSS) gibi güvenlik sorunlarına yol açabilir veya saldırganların arayüz ekleme yoluyla güvenilmeyen içerik yüklemesine ve ana makine uygulamasını istenmeyen şekillerde değiştirmesine olanak tanıyarak ana makine uygulamasının izinleriyle Java kodu yürütmesine neden olabilir.
Çözümler
JavaScript'i devre dışı bırak
WebView'ın JavaScript gerektirmediği senaryolarda WebSettings içinde setJavaScriptEnabled işlevini çağırmayın (örneğin, statik HTML içeriği görüntülerken). Varsayılan olarak, WebView'da JavaScript yürütme devre dışıdır.
Güvenilmeyen içerik yüklenirken JavaScript arayüzünü kaldırma
Güvenilir olmayan içerik WebView tarafından yüklenmeden önce, JavaScript arayüzündeki nesnelerin removeJavascriptInterface çağrılarak kaldırıldığından emin olun. Örneğin, bu işlem shouldInterceptRequest çağrısında yapılabilir.
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Yalnızca HTTPS üzerinden web içeriği yükleme
Güvenilmeyen içerik yüklemeniz gerekiyorsa WebView'un web içeriğini şifrelenmiş bir bağlantı üzerinden yüklediğinden emin olun (Şifrelenmemiş İletişim ile ilgili kurallarımıza da göz atın). android:usesCleartextTraffic değerini false olarak ayarlayarak AndroidManifest dosyasında ilk sayfa yüklemesinin şifrelenmemiş bağlantılarda yapılmasını engelleyin veya ağ güvenliği yapılandırmasında HTTP trafiğine izin vermeyin. Daha fazla bilgi için usesCleartextTraffic belgelerini inceleyin.
Xml
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Yönlendirmelerin ve daha fazla uygulama taramasının şifrelenmemiş trafikte gerçekleşmediğinden emin olmak için loadUrl veya shouldInterceptRequest içinde HTTP şemasını kontrol edin:
Kotlin
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
Java
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
Güvenilmeyen içeriği doğrulama
Bir WebView'da harici bağlantılar yükleniyorsa hem şemayı hem de ana makineyi (izin verilenler listesindeki alanlar) doğrulayın. İzin verilenler listesinde olmayan alanlar bunun yerine varsayılan tarayıcıda açılmalıdır.
Güvenilmeyen içerikleri yüklemeyin
Mümkünse WebView'a yalnızca uygulama geliştiricisine ait olup kapsamı katı bir şekilde belirlenmiş olan URL ve içerikleri yükleyin.
Hassas verileri açığa çıkarmayın
Uygulamanız bir WebView ile hassas verilere erişiyorsa JavaScript arayüzünü kullanmadan önce yerel olarak depolanan dosyaları silmek için clearCache yöntemini kullanmayı düşünebilirsiniz. Bir uygulamanın belirli içerikleri önbelleğe almaması gerektiğini belirtmek için no-store gibi sunucu tarafı üstbilgilerini de kullanabilirsiniz.
Hassas işlevleri kullanıma sunmayın
Uygulamanız hassas izinler gerektiriyorsa veya hassas veriler topluyorsa bunun uygulama içindeki koddan çağrıldığından ve kullanıcılara belirgin bir açıklama yapıldığından emin olun. Hassas işlemler veya kullanıcı verileri için JavaScript arayüzlerini kullanmaktan kaçının.
hedef API düzeyi 21 veya üstünü hedefleyin
addJavascriptInterface yöntemini kullanmanın güvenli bir yolu, yöntemin yalnızca API düzeyi 21 veya üstünde çalışırken çağrılmasını sağlayarak hedef API düzeyi 21 veya üstünü hedeflemektir. API 21'den önce JavaScript, yansıtma kullanarak yerleştirilmiş bir nesnenin herkese açık alanlarına erişebiliyordu.
Risk: MessageChannel riskleri
postWebMessage() ve postMessage()'de kaynak denetiminin olmaması, saldırganların iletileri engellemesine veya yerel işleyicilere ileti göndermesine olanak tanıyabilir.
Çözümler
postWebMessage() veya postMessage()'yi ayarlarken hedef kaynak olarak * kullanmaktan kaçının ve bunun yerine beklenen gönderen alanını açıkça belirterek yalnızca güvenilir alanlardan gelen iletilere izin verin.
Kaynaklar
- postMessage() ile ilgili en iyi uygulamalar
- addJavascriptInterface dokümanları
- postMessage() dokümanları
- WebMessagePort.postMessage() belgeleri
- WebViewClient.shouldInterceptRequest dokümanları
- addJavascriptInterface ile ilgili güvenlik tavsiyelerinin dokümanı
- clearCache belgeleri
- removeJavascript dokümanları
- WebView'larda JavaScript'i etkinleştirme