Webview loadurl injection
Inyección en loadurl de WebView
Descripción
Webview.loadurl carga una URL determinada en una sesión de WebView. La URL de WebView acepta diferentes esquemas y rutas que pueden llevar a cargar contenido inseguro, a realizar ataques de phishing o, en algunos casos, a explotar una vulnerabilidad de ejecución remota de código (RCE).
Varios parámetros controlan las capacidades de la sesión de WebView, como habilitar JavaScript o el acceso a archivos locales mediante la clase Websettings.
Los atacantes pueden explotar la vulnerabilidad creando HTML o JavaScript malicioso. Un ataque de phishing puede hacerse pasar por un formulario de inicio de sesión falso para robar las credenciales del usuario.
El siguiente es un ejemplo de código Java vulnerable que acepta una URL no confiable desde un Intent:
public class VulnerableBrowserActivity extends Activity {
@override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create a new wevbiew session.
WebView webView = (WebView) findViewById(R.id.webview);
// Enable javascript.
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
// Accept url from untrusted intent.
String url = getIntent().getStringExtra("URL");
webView.loadUrl(url);
}
}
Recomendación
Todas las URL no confiables deben tener una validación de entrada adecuada para garantizar que solo se acceda a contenido de confianza. Por ejemplo, si la aplicación está cargando recursos locales, la lista de URL cargadas debe estar en una lista blanca (whitelist).
Los ajustes del Webview también deben endurecerse, eliminando todos los ajustes que no sean necesarios, como JavaScript o el acceso a archivos.
public class WhitelistBrowserActivity extends Activity {
private static WHITELISTED_URLS = ImmutableList.of(
"url1",
"url2");
@override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView webView = (WebView) findViewById(R.id.webview);
String url = getIntent().getStringExtra("url");
if (!WHITELISTED_URLS.contains(url)) { /* Note: "https".startsWith("http") == true */
url = "about:blank";
}
webView.loadUrl(url);
}
}
```dart
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter/material.dart';
class SafeWebViewWidget extends StatelessWidget {
final String untrustedUrl;
static const List
SafeWebViewWidget({required this.untrustedUrl});
@override Widget build(BuildContext context) { // Validate the incoming URL against the whitelist String safeUrl = "about:blank"; if (WHITELISTED_URLS.contains(untrustedUrl)) { safeUrl = untrustedUrl; }
return InAppWebView(
initialUrlRequest: URLRequest(url: WebUri(safeUrl)),
initialSettings: InAppWebViewSettings(
// Harden settings by disabling features if not strictly required
javaScriptEnabled: false,
allowFileAccess: false,
allowFileAccessFromFileURLs: false,
allowUniversalAccessFromFileURLs: false,
),
);
} } ```
Enlaces
- DRD02-J. Do not allow WebView to access sensitive local resource through file scheme
- Webview loadurl (Android documentation)
- Websettings (Android documentation)
Estándares
- OWASP_MASVS_L1:
- MSTG_PLATFORM_7
- MSTG_PLATFORM_2
- OWASP_MASVS_L2:
- MSTG_PLATFORM_7
- MSTG_PLATFORM_2
- PCI_STANDARDS:
- REQ_2_2
- REQ_6_2
- REQ_6_3
- REQ_11_3
- OWASP_MASVS_v2_1:
- MASVS_CODE_4
- MASVS_PLATFORM_2
- SOC2_CONTROLS:
- CC_2_1
- CC_3_4
- CC_4_1
- CC_7_1
- CC_7_2
- CC_7_4
- CC_7_5
- OWASP_MOBILE_TOP_10:
- M4_2024