Webview loadurl injection
Webview loadurl injection
Description
Webview.loadurl loads a given URL into a webview session. Webview url
accepts different urls schemes and paths that can lead to loading of
insecure content, perform phishing attacks or in some cases exploit a
remote code execution vulnerability.
Several settings controls the capabilities of the webview session, like
enabling javascript or local file access using the Websettings class.
Attackers can exploit the vulnerability by crafting malicious HTML or Javascript. A phishing attack can pass as a fake login form to steal the user\'s credentials.
The following is an example a vulnerable Java code accepting untrusted URL from an 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);
}
}
Recommendation
All untrusted URLs must have proper input validation to ensure only trusted content is accessible. For instance, if the application is loading local assets, the list of loaded URLs must be whitelisted.
The Webview settings must also be hardened, removing all non required
settings, like javascript or file access.
```java 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,
),
);
} } ```
Links
- DRD02-J. Do not allow WebView to access sensitive local resource through file scheme
- Webview loadurl (Android documentation)
- Websettings (Android documentation)
Standards
- 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