セキュリティ・ガイド
このセキュリティ・ガイドでは、GraalVMのセキュリティ・モデルと機能に関する情報を、それに基づいてセキュアなアプリケーションを構築することを目指す開発者および埋込み担当者に提供します。読者にGraalVMアーキテクチャに関する知識があることを前提としています。このガイドは、Javaのセキュリティ・ドキュメントに置き換わるものではなく、GraalVM固有の側面で補足するものです。また、セキュリティ研究者にGraalVMのセキュリティ・モデルに関する情報を提供します。
セキュリティ・モデル
GraalVMは共有ランタイムです。上位レベルのプログラミング言語(またはその中間表現)の命令を後で実行される入力として受け入れます。GraalVMによって実行されているコードでアプリケーションのセキュリティ制御(アクセス制御など)を実装する開発者は、命令の正しい実行を確保できます。GraalVM上で実行されている、このようなセキュリティ制御をバイパスできるセキュリティ・クリティカルなコードの不適切な実行は、セキュリティの脆弱性とみなされます。
デバッグ機能は、アプリケーションへの特権アクセスを提供し、その状態と動作を検査および変更できるため、信頼できる環境でのみ使用する必要があります。これらは、さらにネットワーク・ソケットを開いて、デバッグ・クライアントが接続できるようにする場合があります。
GraalVMの試験段階の機能は本番での使用を意図しておらず、セキュリティ・ガイドに記載されていないセキュリティ制限がある場合があります。
GraalVMは、適切に構成されたポリグロット実行コンテキストで信頼できないコードを実行できます(「ポリグロット・サンドボックス化」を参照)。
脆弱性の報告ガイドに記載されているプロセスを通じて、セキュリティ・モデルを壊すバグをご報告いただくことを歓迎します。
ポリグロット言語
GraalVMに付属しているすべてのポリグロット言語に対して、対話型シェルなどのランチャが用意されています。これらのランチャは同じように動作し、元のランチャと同じセキュリティ保証が付属しています。
ポリグロット・サンドボックス化
ポリグロット・サンドボックス化により、特権ホスト・コードと非特権ゲスト・コードの間にセキュリティ境界を確立できます。詳細は、ポリグロット・サンドボックス化のガイドを参照してください。
ScriptEngineの互換性
下位互換性のために、特定のポリグロット言語ではJava Scripting APIもサポートされます。たとえば、これにより、GraalVM JavascriptランタイムをNashornのドロップイン代替として使用できます。ただし、互換性を維持するために、Nashorn GraalVM JavaScript ScriptEngineインタフェースでは、スクリプトに付与されたすべての権限を持つコンテキストが作成されるため、信頼できるコードに対してのみ細心の注意を払って使用する必要があります。
ネイティブ・コードの管理対象実行
ポリグロット埋込みでは、LLVM中間表現(IR)ゲスト・コードもサポートされます。いくつかのネイティブ・システム・プログラミング言語、特にC/C++は、LLVMコンパイラ・ツールチェーンを使用してLLVM IRにコンパイルできます。通常、これらの言語は、管理された実行を使用しないかぎりメモリー安全性がなく、多くの場合、メモリー安全性の違反はセキュリティの脆弱性の原因となることに注意してください。
管理対象モードでは、オペレーティング・システムを含む管理されていないコードへのすべてのアクセスは、言語ランタイムによって仲介されます。具体的には、次のことを意味します:
- 一時メモリーと空間メモリー安全性に関しては、メモリーはJavaヒープから割り当てられます。これは、メモリー割当てが管理対象オブジェクトで、かつすべてのアクセスがメモリー安全性のある方法で実行されることを意味します(任意のポインタ演算および未チェックの範囲外アクセスはありません)。
- 型安全性に関しては、データ・ポインタを関数ポインタに再解釈して任意の命令を実行することはできません(これらはLLVMランタイムの個別のポインタ型であるため)。
- システム・コールはインターセプトされ、対応するTruffle APIにルーティングされます。たとえば、ファイルIOはTruffle
FileSystem
APIにマップされます。現在サポートされている一連のシステム・コールは非常に限定的です。Truffle APIレベルに安全にマップできるシステム・コールのみを使用できます。管理対象モードのLLVMランタイムでは、Linux/x86用にコンパイルされたビットコードが常に実行されるため、実装する必要があるのはこのプラットフォームのシステム・コールのみです。 - すべての依存ライブラリも管理対象モードで実行され、ネイティブに実行されたシステム・ライブラリへのすべての参照が削除されます。これには、muslibcなど、LLVMランタイムによって提供されるライブラリが含まれます。
管理対象モードは、コンテキスト(Context.create())
を作成するとき、または--llvm.managed
オプションを指定してbin/lli
バイナリをコールするときに選択できます。管理対象コンテキストは、コンテキストの作成中に渡される制限(allowIO
など)に準拠するため、allowNativeAccess
権限は必要ありません。
ネイティブ・イメージ
GraalVMネイティブ・イメージでは、起動後にアプリケーションの状態が取得され、到達可能なすべてのコードが事前にコンパイルされて、ネイティブ実行可能ファイルとしてバンドルされます。詳細は、ネイティブ・イメージのセキュリティ・ガイドを参照してください。
セキュリティ・マネージャ
セキュリティ・マネージャはJEP-411で非推奨になりました。OpenJDK脆弱性グループは、セキュリティ・マネージャの下で信頼できないコードを実行しないことを強く推奨しています。このことは、Javaでの信頼できないコードの実行をサポートしていないGraalVMにも当てはまります。
GraalVM Community Editionのダウングレード
ポリグロット・サンドボックス化は、GraalVM Community Editionでは使用できません。ネイティブ・コードの管理された実行は、GraalVM Community Editionでは使用できません。
GraalVM Community Editionにダウングレードする場合、ネイティブ・コードの実行はallowNativeAccess
権限でのみ可能です。このことは、PythonやRubyなど、Truffleで実装され、ネイティブ・コード拡張を可能にする言語にも適用されます。