簡體   English   中英

如何在沙盒中使用Rhino for Java運行Javascript?

[英]How can you run Javascript using Rhino for Java in a sandbox?

我們的Java應用程序的一部分需要運行由非開發人員編寫的javascript。 這些非開發人員使用javascript進行數據格式化。 (主要是簡單的邏輯和字符串連接)。

我的問題是如何設置這些腳本的執行以確保腳本錯誤不會對應用程序的其余部分產生重大負面影響。

  • 需要防范無限循環
  • 防止產生新線程。
  • 限制對服務和環境的訪問
    • 文件系統(示例:如果心懷不滿的腳本編寫者決定刪除文件)
    • 數據庫(同樣刪除數據庫記錄)

基本上我需要設置javascript范圍,只包括他們需要的內容,而不是更多內容。

為了防止無限循環,您可以在腳本運行時觀察指令計數(這僅適用於已解釋的腳本,而不適用於已編譯的腳本)。

Rhino JavaDocs中有一個例子可以防止腳本運行超過十秒:

 protected void observeInstructionCount(Context cx, int instructionCount)
 {
     MyContext mcx = (MyContext)cx;
     long currentTime = System.currentTimeMillis();
     if (currentTime - mcx.startTime > 10*1000) {
         // More then 10 seconds from Context creation time:
         // it is time to stop the script.
         // Throw Error instance to ensure that script will never
         // get control back through catch or finally.
         throw new Error();
     }
 }

要阻止Java類和方法訪問,請看...

http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

為了防止無限循環,你需要將它放在一個單獨的進程中,以便它可以被殺死。

為了防止創建線程,您需要擴展SecurityManager(默認實現允許不受信任的代碼訪問非根線程組)。

Java安全性允許您阻止對文件系統的訪問。

對於數據庫限制,您可能能夠使用標准SQL用戶安全性,但這非常弱。 否則,您需要提供一個強制執行限制的API。

編輯:我應該指出,JDK6提供的Rhino版本已經完成了安全工作,但不包括編譯器。

我剛剛瀏覽了這個博客帖子,似乎對沙箱或多或少的任何東西都有用(不僅僅是Rhino):

http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

如果您只是在尋找純JavaScript函數,這里是一個基於JDK嵌入式Rhino庫的解決方案,無需導入任何第三方庫:

  1. 通過ScriptEngineManager#getEngineFactories找出JavaScript腳本引擎工廠類名
  2. 在新的類加載器中加載腳本引擎工廠類,其中將忽略JavaMembers或其他相關類。
  3. 在已加載的腳本引擎工廠上調用#getScriptEngine,在返回的腳本引擎上調用eval腳本。

如果給定腳本包含Java腳本,則類加載器將嘗試加載JavaMembers或其他類並觸發類未找到的異常。 這樣,惡意腳本將被忽略而不執行。

有關更多詳細信息,請閱讀ConfigJSParser.java和ConfigJSClassLoader.java文件:

https://github.com/webuzz/simpleconfig/tree/master/src/im/webuzz/config

Javascript是單線程的,無法訪問文件系統,所以我認為你不必擔心這些。 我不確定是否有辦法設置超時以防止無限循環,但你總是可以生成一個執行腳本的(Java)線程,然后在這么多時間后終止線程。

暫無
暫無

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

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