ある種の組み合わせのパーミッションは、大きな権限を与えてしまうため、割り当てるべきではない。それ以外のパーミッションを、それを必要とする特別なコードにだけ割り当てるべきである。
AllPermission
java.security.AllPermission は、すべてのパーミッションをコードに割り当てる。このパーミッションは、定期的に動作試験を行う場合や、コード全体が信頼できる場合に、複数のパーミッションを管理する手間を省くために設けられたものである。通常、コードに AllPermission を割り当てる場合にはセキュリティポリシーファイルを使う。ProtectionDomain クラスを使ってプログラムから AllPermission を割り当てることもできる。実運用環境でこのパーミッションを使うのは危険である。信頼できないコードには AllPermission を割り当てないこと。
ReflectPermission, suppressAccessChecks
ターゲットとして suppressAccessChecks を指定した ReflectPermission を割り当てることにより、コードが他のクラスのパッケージプライベート、protected、private なメンバにアクセスしようとしたときに行われる、Java 言語の標準のアクセスチェックが抑制される。そのため、このパーミッションが与えられたコードは、任意のクラスのすべてのメンバにアクセスでき、また、どんなメソッドも呼び出せることになる[Reflect 2006]。よって、ターゲットとして suppressAccessChecks を指定した ReflectPermission の割当てを行ってはいけない。
「Java SE 6 Development Kit (JDK) でのアクセス権」のセクション ReflectPermission では、ターゲット名 suppressAccessChecks は以下のように説明されている。
警告: このアクセス権をコードに与えるときは、細心の注意を払うこと。このアクセス権により、クラスのフィールドへのアクセスとメソッドの呼出しが可能になる。public のほか、protected、private などのフィールドおよびメソッドも含まれる。
RuntimePermission, createClassLoader
ターゲットとして createClassLoader を指定した java.lang.RuntimePermission を割り当てられたコードは、ClassLoader オブジェクトを生成できるようになる。これは非常に危険である。このパーミッションが割り当てられた攻撃コードは、独自のクラスローダを作成し、任意のパーミッションを割り当てたクラスをロードすることが可能になるからである。独自のクラスローダは、システムセキュリティポリシーファイルで規定された制限を上書きするパーミッションを割り当てたクラス(あるいは ProtectionDomain)を定義できる。
「Java SE 6 Development Kit (JDK) でのアクセス権」には、以下のように記述されている[Permissions 2008]。
このアクセス権を与えるのは極めて危険である。悪意のあるアプリケーションが独自のクラスローダのインスタンスを生成し、破壊行為を行うクラスをシステムにロードする可能性がある。この新たにロードされたクラスが同じクラスローダによって保護ドメインに置かれ、ロードされたクラスに、そのドメインのアクセス権が自動的に与えられる可能性がある。
違反コード (セキュリティポリシーファイル)
以下の違反コード例では、klib ライブラリに AllPermission を割り当てている。
// klib ライブラリに AllPermission を割り当て grant codebase "file:${klib.home}/j2se/home/klib.jar" { permission java.security.AllPermission; };
このように、パーミッション自体は、セキュリティマネージャが使用するセキュリティポリシーファイルの中で指定される。プログラムからは、java.security.Permission クラスやそのサブクラス(BasicPermission など)を拡張することによってパーミッションオブジェクトを取得することができる。さらに、取得したオブジェクトを使って、特定の ProtectionDomain に AllPermission を割り当てることができる。
適合コード
以下の適合コードは、粒度の細かいパーミッション設定を行うためのポリシーファイルの例を示している。
grant codeBase "file:${klib.home}/j2se/home/klib.jar", signedBy "Admin" { permission java.io.FilePermission "/tmp/*", "read"; permission java.io.SocketPermission "*", "connect"; };
呼出し元が必要とされるパーミッションを持っているかどうか確認するには、標準 Java API では以下のように書く。
// セキュリティマネージャによるチェック FilePermission perm = new java.io.FilePermission("/tmp/JavaFile", "read"); AccessController.checkPermission(perm); // ...
コードには常に適切なパーミッションを割り当てること。標準的なパーミッションでは粒度が大き過ぎる場合は、独自のパーミッションを設定を行うこと。
違反コード (PermissionCollection クラス)
以下の違反コード例では、独自のクラスローダを使って getPermissions() メソッドをオーバーライドしている。このクラスローダは、ロードするすべてのクラスに、ターゲット suppressAccessChecks を指定したパーミッション java.lang.ReflectPermission を割り当てている。
protected PermissionCollection getPermissions(CodeSource cs) { PermissionCollection pc = super.getPermissions(cs); // クラスローダを作るためのパーミッション pc.add(new ReflectPermission("suppressAccessChecks")); // 他のパーミッション return pc; }
適合コード
以下の適合コードでは、ロードするどのクラスにも、ターゲット suppressAccesschecks を指定した java.lang.ReflectPermission を割り当てない。
protected PermissionCollection getPermissions(CodeSource cs) { PermissionCollection pc = super.getPermissions(cs); // 他のパーミッション return pc; }
例外
ENV03-EX0: コールバックが適切に動作できるように、信頼できるライブラリコードには AllPermission を割り当てる必要があるかもしれない。たとえば、追加の Java パッケージ(拡張ライブラリ)に AllPermission を割り当てることはよく行われており、このルールの例外として許容される。
// 標準拡張はコア部分の機能を拡張するもので、デフォルトですべてのパーミッションが割り当てられる grant codeBase "file:${{java.ext.dirs}}/*" { permission java.security.AllPermission; };
リスク評価
信頼できないコードに AllPermission を割り当てると、特権を持った操作を許してしまう危険がある。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
ENV03-J | 高 | 高 | 低 | P27 | L1 |
自動検出
危険なパーミッションの割当てを静的コード解析で検出するのは容易である。パーミッション割当てが 正しい かどうかを自動的に判別するのは不可能である。
関連する脆弱性
CVE-2007-5342 は、Apache Tomcat 5.5.9 から 5.5.25 までのバージョンと 6.0.0 から 6.0.15 までのバージョンに存在する脆弱性について記述している。JULI ログコンポーネントで使われているセキュリティポリシーは、制限すべきパーミッションを web アプリケーションに割り当ててしまっていたため、攻撃者は org.apache.juli.FileHandler ハンドラのログレベル、ディレクトリ、プレフィクスといった属性を変更することができた。これによってログの設定を変更し、任意のファイルを上書きすることが可能になっていた。
関連ガイドライン
MITRE CWE | CWE-732. Incorrect permission assignment for critical resource |
参考文献
[API 2006] | Class AllPermission, ReflectPermission, RuntimePermission |
[Gong 2003] | |
[Long 2005] | Section 2.5, Reflection |
[Permissions 2008] | Section ReflectPermission |
[Reflect 2006] | |
[Security 2006] | Security Architecture, Section RuntimePermission |
翻訳元
これは以下のページを翻訳したものです。
ENV03-J. Do not grant dangerous combinations of permissions (revision 102)