Many apps are not written in Java or Kotlin, but get implemented in Javascript and HTML that then gets rendered in a WebViews.
So when looking for security issues in apps, WebViews are a very important attack surface. In very old Android versions (2013), WebViews were very insecure and could even lead to arbitrary code execution. However in modern Android, this is not possible anymore.
Besides WebViews, there also exists so called Custom Tabs. This is a more modern feature
The WebView class is an extension of Android's View class that lets you display web pages as a part of your activity layout. It doesn't include the features of a fully developed web browser, such as navigation controls or an address bar. All WebView does, by default, is show a web page.
A WebView is an actual UI component that can be added into the layout .xml of the app. e.g. It is same as you adding a button in UI.
The WebView element can then be referenced in the application code to load a URL in it.
and an embedded browser will load your url but remember you won't have features like searchbar like traditional browser.
Webview in browser
navigating to chrome://inspect/#devices in your host machine browser. You get webview debugging interface.
Sometimes it is enabled in production also deliberately which might become a issue, using this function
setWebContentsDebuggingEnabled(true)
where in app assets directory we have index.html.
While WebView often serves content from the internet, it can also load local HTML and JavaScript files from within the app itself. This is useful for offline functionality or even when the app is entirely implemented in HTML and Javascript.
Android applications can include an /assets/ folder in their project structure. This folder is bundled into the final APK and is accessible at runtime. And WebView has a built in feature to load these files via file:///android_asset/ (or file:///android_res/):
Because asset files are bundled in the APK publicly distributed in the Play Store, they are considered public. That's why WebViews can load them even when file access is generally not enabled. To be able to load other app internal files, the WebView WebSettings have to be changed:
Some settings like setAllowUniversalAccessFromFileURLs are very dangerous, but might still be required by some apps. We will look deeper into those settings as well.
JavaScriptInterface
WebViews in Android can allow JavaScript running in the WebView to call native Java methods. This is especially useful if the app logic is primarily implemented in HTML/Javascript and wants to access native Android features.
If an attacker can control the document loaded into a WebView, these exposed Java methods could lead to security issues.
e.g.
public class Flag38WebViewsActivity extends AppCompatActivity {
public static String secret = UUID.randomUUID().toString();
class JsObject {
JsObject() {
}
@JavascriptInterface
public void toastDemo() {
Toast.makeText(Flag38WebViewsActivity.this.getApplicationContext(), "Called from WebView", 0).show();
}
@JavascriptInterface
public String success(boolean z) {
if (z) {
Flag38WebViewsActivity.this.success();
return "success(true)";
}
return "success(Boolean secret) requires `true` parameter";
}
}
@Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_web_view);
String stringExtra = getIntent().getStringExtra("URL");
if (stringExtra == null) {
stringExtra = "file:///android_asset/flag38.html";
}
((TextView) findViewById(R.id.txt_webview_header)).setText(getClass().getSimpleName());
((TextView) findViewById(R.id.txt_webview_subtitle)).setText(stringExtra);
final WebView webView = (WebView) findViewById(R.id.main_webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "hextree");
webView.loadUrl(stringExtra);
findViewById(R.id.button_back).setOnClickListener(new View.OnClickListener() { // from class: io.hextree.attacksurface.webviews.Flag38WebViewsActivity$$ExternalSyntheticLambda0
@Override // android.view.View.OnClickListener
public final void onClick(View view) {
Flag38WebViewsActivity.this.m160x89ddf80a(view);
}
});
in this activity you can see onload a webview is loaded with URL file:///android_asset/flag38.html whose content is
Most important thing, in webview we are adding a javascript<->java bridge of class JsObject with name hextree
which allows js in webview to call methods of class JsObject with name hextree. As you have seen in html e.g. hextree.success.
Not every function from Jsobject class is exposed this way, only annotated with @JavascriptInterfaceare exposed to webview JS.
solution,
as you can see if an intent is provided with URL then that URL is loaded in webview. which means which can call success() function with folllowing html file.