JPCERT コーディネーションセンター

ENV03-J. 危険な組み合わせのパーミッションを割り当てない

ある種の組み合わせのパーミッションは、大きな権限を与えてしまうため、割り当てるべきではない。それ以外のパーミッションを、それを必要とする特別なコードにだけ割り当てるべきである。

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 など)を拡張することによってパーミッションオブジェクトを取得することができる。さらに、取得したオブジェクトを使って、特定の ProtectionDomainAllPermission を割り当てることができる。

適合コード

以下の適合コードは、粒度の細かいパーミッション設定を行うためのポリシーファイルの例を示している。

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)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter