- 適用於 JDK 23 的 GraalVM (最新)
- 適用於 JDK 24 的 GraalVM (搶先體驗)
- 適用於 JDK 21 的 GraalVM
- 適用於 JDK 17 的 GraalVM
- 封存
- 開發版本
安全指南
本安全指南提供有關 GraalVM 安全模型和功能的資訊,適用於希望在其之上建構安全應用程式的開發人員和嵌入者。它假設讀者熟悉 GraalVM 架構。本指南並非取代 Java 安全性文件,例如 Java SE 的安全編碼指南,而是補充 GraalVM 獨有的面向。
安全模型 #
GraalVM 是一個共享執行時環境。它接受較高階程式設計語言(或其的中間表示形式)的指令作為輸入,並在稍後執行。在 GraalVM 上執行的程式碼中實作應用程式安全控制(例如存取控制)的開發人員可以依靠指令的正確執行。在 GraalVM 上執行的安全關鍵程式碼執行不正確,而允許繞過此類安全控制,則被視為安全性漏洞。
偵錯功能應僅在受信任的環境中使用,因為它們提供對應用程式的特權存取,允許檢查和變更其狀態和行為。它們可能還會開啟網路通訊端,以允許偵錯用戶端連線。
GraalVM 中的實驗性功能不適用於生產環境,並且可能具有安全指南中未涵蓋的安全性限制。
GraalVM 允許在適當設定的多語言執行內容中執行不受信任的程式碼(請參閱沙箱化)。
我們歡迎透過回報漏洞指南中概述的程序回報破壞安全模型的錯誤。
Graal 語言 #
每個語言執行階段,通常隨 GraalVM 版本一起提供,都提供一個啟動器,例如互動式 Shell。這些啟動器的行為方式相同,並具有與其「原始」對應物相同的安全性保證。
沙箱化 #
沙箱化可以在特權主機程式碼和非特權客體程式碼之間建立安全邊界,這可以透過 Polyglot API 來實現。如需更多資訊,請參閱沙箱化文件。
ScriptEngine 相容性 #
由於回溯相容性的原因,某些 Polyglot 語言也支援Java Scripting API。例如,這允許將 GraalVM Javascript 執行階段用作 Nashorn 的直接取代。但是,為了保持相容性,Nashorn GraalVM JavaScript ScriptEngine 介面將建立一個內容,並將所有權限授予指令碼,應極其謹慎地使用,且僅用於受信任的程式碼。
原生程式碼的受管理執行 #
Polyglot 嵌入也支援 LLVM 中間表示 (IR) 客體程式碼。許多原生系統程式設計語言(首先是 C/C++)可以使用 LLVM 編譯器工具鏈編譯為 LLVM IR。通常,這些語言除非使用受管理執行,否則不具有記憶體安全,必須記住,違反記憶體安全是造成安全性漏洞的常見原因。
在受管理模式下,所有對非受管理程式碼(包括作業系統)的存取都由語言執行階段仲裁。特別是,這表示
- 在時間和空間記憶體安全性方面,記憶體是從 Java 堆積配置的。這表示記憶體配置是受管理物件,所有存取都以記憶體安全的方式執行(沒有任意指標運算,也沒有未檢查的越界存取)。
- 關於類型安全,不可能將資料指標重新解釋為函式指標並執行任意指令(因為這些是 LLVM 執行階段的不同指標類型)。
- 系統呼叫會被攔截並路由到相應的 Truffle API。例如,檔案 IO 會對應到 Truffle
FileSystem
API。目前支援的系統呼叫集非常有限—僅當可以安全對應到 Truffle API 層級的系統呼叫才可用。由於受管理模式下的 LLVM 執行階段始終執行為 Linux/x86 編譯的位元碼,因此它只需要實作此平台的系統呼叫。 - 所有相依程式庫也都以受管理模式執行,從而移除對原生執行系統程式庫的所有參考。這包括 LLVM 執行階段提供的程式庫,例如 muslibc。
在建立內容時 (Context.create()
) 或透過指定 --llvm.managed
選項來呼叫 bin/lli
二進位檔時,可以選擇受管理模式。「受管理」內容將遵循在內容建立期間傳遞的任何限制(例如,allowIO
),並且不需要 allowNativeAccess
權限。
Native Image #
使用 GraalVM Native Image,應用程式的狀態會在啟動後擷取,並且所有可到達的程式碼都會提前編譯,以作為原生可執行檔捆綁在一起。如需更多資訊,請參閱原生映像安全性指南。
安全管理員 #
安全管理員已在 JEP-411 中遭到棄用。GraalVM 不支援在 Java 中執行不受信任的程式碼。
GraalVM Community Edition 降級 #
GraalVM Community Edition 中不提供沙箱化。GraalVM Community Edition 中不提供原生程式碼的受管理執行。
當降級到 GraalVM Community Edition 時,原生程式碼執行只能使用 allowNativeAccess
權限。這也適用於使用 Truffle 實作並允許原生程式碼擴充功能的語言,例如 Python 和 Ruby。