Java のソースコードをコンパイルすると、バイトコードに変換され、1つ以上のクラスファイルに出力され、そして JVM で実行される。Java のクラスファイルがコンパイルされる環境と実行される環境は異なるかもしれない。適切に生成されたクラスファイルは 正当(conforming) であると言う。JVM がクラスファイルをロードするとき、クラスファイルが正当なものであるかどうかを知る手段はない。クラスファイルは他のプロセスによって生成されたものかもしれないし、攻撃者がなんらかの変更を加えているかもしれない。
Java バイトコード検証器(Java bytecode verifier)は、正当でないバイトコードを検出する役割を果たす JVM 内部のコンポーネントである。クラスファイルが Java クラスファイル形式に沿ったものであること、不正な型キャストが行われていないこと、オペランドスタックのアンダーフローが発生しないこと、各メソッドがオペランドスタックに積んだものをすべて取り出していること、を検証する。
ユーザは、信頼できる情報源から入手した Java クラスファイルは正当なものであり、実行しても安全であると通常考える。そのように思ってしまうと、信頼できる情報源から入手したクラスファイルに対するバイトコード検証は無駄な処理だと考え、バイトコード検証を無効にしてしまうかもしれない。しかし、バイトコード検証を無効にすると、Java の安全性とセキュリティを保証する仕組みを損なってしまう。バイトコード検証器を無効にしてはならない。
違反コード
バイトコード検証はデフォルトで実行される。以下のように、JVM に -Xverify:none フラグを渡して実行すると、バイトコード検証は行われなくなる。
java -Xverify:none ApplicationName
適合コード
ほとんどの JVM 実装は、バイトコード検証をデフォルトで実行する。動的にクラスをロードする場合にもバイトコード検証が行われる。
以下のように、-Xverify:all フラグを指定することで、JVM にバイトコード検証を強制的に実行させることができる。
java -Xverify:all ApplicationName
例外
ENV04-EX0: Java 2 システムでは、ブートストラップ(primordial)クラスローダは、ブートクラスパスからロードしたクラスのバイトコード検証を省略することが許される。これらのシステムクラスは、バイトコード検証によってではなく、プラットフォームやファイルシステム上の仕組みによって保護される。
リスク評価
バイトコード検証は、Java 言語仕様 で要請されているセキュリティチェックの多くがバイトコードの中に含まれていることを確認する。この検証を省くと、セキュアでない Java コードの実行を許してしまう。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
ENV04-J | 高 | 高 | 低 | P27 | L1 |
自動検出
一般に、静的解析でこのルールの違反を検出することは不可能である。
参考文献
[Oaks 2001] | The Bytecode Verifier |
[Pistoia 2004] | Section 7.3, The Class File Verifier |
翻訳元
これは以下のページを翻訳したものです。
ENV04-J. Do not disable bytecode verification (revision 81)