The Ja-Jakarta ProjectTomcat Servlet/JSP コンテナ

リンク

ユーザガイド

リファレンス

Tomcat開発

Tomcat5 サーブレット/JSP コンテナ

セキュリティマネージャ設定方法

Printer Friendly Version
印刷用
バージョン
背景

Java SecurityManager は、 信頼されていないコードがローカルファイルシステムにあるファイルへアクセスしたり、 アプレットのダウンロード元のホスト以外と通信したりといったことができないように、 Web ブラウザがアプレットを砂箱(サンドボックス, sandbox)内で実行できるようにする機構です。 SecurityManagerがブラウザでの信頼されていないアプレットの実行を防ぐのと同じように、 Tomcat実行中のSecurityManager利用により、 「トロイの木馬」タイプのサーブレット、JSP、JSP内のBean、タグライブラリからサーブレットを保護できます。 また不注意による間違いからも保護できます。

あなたのサイトでJSPを発行できるユーザが次のような内容を含むJSPを誤って置いてしまったとしましょう。

<% System.exit(1); %>

TomcatでこのJSPが実行されるたびに、Tomcatは停止するでしょう。 Java SecurityManagerを利用することで、 システム管理者はサーバの安全性と信頼性をより一層確保できるのです。

警告 - セキュリティ監査はTomcat 5のコードベースを使って管理されています。 重要なパッケージのほとんどは保護されており、新しいセキュリティパッケージ保護機構も実装されています。 それでも、十分な信頼を置けないユーザへWebアプリケーション、JSP、サーブレット、 Beans、 タグライブラリの発行を許可する前に、 SecurityManagerの設定は要求を満足しているかを確認して下さい。 しかしながら、 SecurityManagerを使って実行する方が、しないより良いのは明らかです。

パーミッション

パーミッションクラスはTomcatによってロードされたクラスがどんなパーミッションを持つかを定義するために使われます。 JDKには標準で多くのパーミッションクラスがあります。 自作のWebアプリケーション用に独自のパーミッションクラスを作成することもできます。 Tomcat 5ではどちらのテクニックも使われています。

標準パーミッション

これはTomcatへ適用可能な、標準システムSecurityManagerパーミッションクラスの概要に過ぎません。 詳細は http://java.sun.com/security/ をご覧下さい。

  • java.util.PropertyPermission - java.homeといったJVMのプロパティの読込/書込アクセス制御。
  • java.lang.RuntimePermission - exit()exec()のようないくつかのSystem/Runtime関数の使用を制御。 パッケージのアクセス/定義も制御。
  • java.io.FilePermission - ファイル、ディレクトリへ読込/書込/実行のアクセス制御。
  • java.net.SocketPermission - ネットワークソケット使用の制御。
  • java.net.NetPermission - マルチキャストネットワーク接続使用の制御。
  • java.lang.reflect.ReflectPermission - クラスイントロスペクション(class introspection)を行なうためのリフレクション使用の制御。
  • java.security.SecurityPermission - セキュリティメソッドへのアクセスを制御。
  • java.security.AllPermission - すべてのパーミッションへのアクセスを許可。 TomcatをSecurityManagerなしで実行するのと同様。
Tomcatカスタムパーミッション

Tomcatは、org.apache.naming.JndiPermissionというカスタムパーミッションクラスを利用します。 このパーミッションはJNDIで名前付けされたファイルベースリソースの読み込みアクセスを制御します。 [ポリシーファイルでは]パーミッション名はJNDI名と同じになり、アクションは記述しません。 パーミッションを与える時に、JNDIで名前付けされたファイルリソースに対してワイルドカード一致を行なうために、 最後に"*"をつけることができます。 例えば、ポリシーファイル内に次のように記述できます。

permission  org.apache.naming.JndiPermission  "jndi://localhost/examples/*";

このようなパーミッションエントリは配備されるWebアプリケーションごとに動的に生成されます。 Webアプリケーション自身の静的なリソースの読込は許可しますが、 その他のファイルの読込はすべて許可しないようにするためです。 (それらのファイルに対するパーミッションが明示的に許可されている場合は除きます)。

その上、Tomcatは常に以下のようなファイルパーミッションを動的に作成します。

  
permission java.io.FilePermission "** your application context**", "read";

**your application context**のところにはアプリケーションが配備されている配下のフォルダ (またはWARファイル)名が入ります。

SecurityManagerを使ったTomcatの設定

ポリシーファイルの書式

Java SecurityManagerによって実装されているセキュリティポリシーは、 $CATALINA_HOME/conf/catalina.policyファイルで設定できます。 このファイルはJDKシステムディレクトリにあるjava.policyファイルを完全に置き換えます。 catalina.policyファイルは手作業でも編集可能ですし、 Java 1.2以降に付属する policytool アプリケーションを利用することもできます。

catalina.policyファイルのエントリは、以下の例のように、 標準java.policyファイルの書式を利用します。

// Example policy file entry

grant [signedBy <signer>,] [codeBase <code source>] {
  permission  <class>  [<name> [, <action list>]];
};

signedBycodeBaseエントリは、 パーミッションを与える時のオプション設定です。 コメント行は"//"で始まり、終わりはその行の最後までになります。 codeBaseはURL形式で、 ファイルURLでは${java.home}${catalina.home}プロパティ (JAVA_HOMECATALINA_HOME環境変数で定義されたディレクトリパスを展開したもの) が使えます

配布時のポリシーファイル

配布時の$CATALINA_HOME/conf/catalina.policyファイルは以下のようになっています。

// ============================================================================
// catalina.corepolicy - Security Policy Permissions for Tomcat 5
//
// This file contains a default set of security policies to be enforced (by the
// JVM) when Catalina is executed with the "-security" option.  In addition
// to the permissions granted here, the following additional permissions are
// granted to the codebase specific to each web application:
//
// * Read access to the document root directory
//
// $Id: security-manager-howto.xml,v 1.3 2004/03/09 07:07:48 tatakaha Exp $
// ============================================================================


// ========== SYSTEM CODE PERMISSIONS =========================================


// These permissions apply to javac
grant codeBase "file:${java.home}/lib/-" {
        permission java.security.AllPermission;
};

// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
        permission java.security.AllPermission;
};

// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/../lib/-" {
        permission java.security.AllPermission;
};

// These permissions apply to all shared system extensions when
// ${java.home} points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/lib/ext/-" {
        permission java.security.AllPermission;
};


// ========== CATALINA CODE PERMISSIONS =======================================


// These permissions apply to the launcher code
grant codeBase "file:${catalina.home}/bin/commons-launcher.jar" {
        permission java.security.AllPermission;
};

// These permissions apply to the server startup code
grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
        permission java.security.AllPermission;
};

// These permissions apply to the servlet API classes
// and those that are shared across all class loaders
// located in the "common" directory
grant codeBase "file:${catalina.home}/common/-" {
        permission java.security.AllPermission;
};

// These permissions apply to the container's core code, plus any additional
// libraries installed in the "server" directory
grant codeBase "file:${catalina.home}/server/-" {
        permission java.security.AllPermission;
};

// ========== WEB APPLICATION PERMISSIONS =====================================


// These permissions are granted by default to all web applications
// In addition, a web application will be given a read FilePermission
// and JndiPermission for all files and directories in its document root.
grant { 
        // Required for JNDI lookup of named JDBC DataSource's and
        // javamail named MimePart DataSource used to send mail
        permission java.util.PropertyPermission "java.home", "read";
        permission java.util.PropertyPermission "java.naming.*", "read";
        permission java.util.PropertyPermission "javax.sql.*", "read";

        // OS Specific properties to allow read access
	permission java.util.PropertyPermission "os.name", "read";
	permission java.util.PropertyPermission "os.version", "read";
	permission java.util.PropertyPermission "os.arch", "read";
	permission java.util.PropertyPermission "file.separator", "read";
	permission java.util.PropertyPermission "path.separator", "read";
	permission java.util.PropertyPermission "line.separator", "read";

        // JVM properties to allow read access
        permission java.util.PropertyPermission "java.version", "read";
        permission java.util.PropertyPermission "java.vendor", "read";
        permission java.util.PropertyPermission "java.vendor.url", "read";
        permission java.util.PropertyPermission "java.class.version", "read";
	permission java.util.PropertyPermission "java.specification.version", "read";
	permission java.util.PropertyPermission "java.specification.vendor", "read";
	permission java.util.PropertyPermission "java.specification.name", "read";

	permission java.util.PropertyPermission "java.vm.specification.version", "read";
	permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
	permission java.util.PropertyPermission "java.vm.specification.name", "read";
	permission java.util.PropertyPermission "java.vm.version", "read";
	permission java.util.PropertyPermission "java.vm.vendor", "read";
	permission java.util.PropertyPermission "java.vm.name", "read";

        // Required for getting BeanInfo
        permission java.lang.RuntimePermission "accessClassInPackage.sun.beans.*";

        // Required for OpenJMX
        permission java.lang.RuntimePermission "getAttribute";

	// Allow read of JAXP compliant XML parser debug
	permission java.util.PropertyPermission "jaxp.debug", "read";
};


// You can assign additional permissions to particular web applications by
// adding additional "grant" entries here, based on the code base for that
// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
//
// Different permissions can be granted to JSP pages, classes loaded from
// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
//
// For instance, assume that the standard "examples" application
// included a JDBC driver that needed to establish a network connection to the
// corresponding database and used the scrape taglib to get the weather from
// the NOAA web server.  You might create a "grant" entries like this:
//
// The permissions granted to the context root directory apply to JSP pages.
// grant codeBase "file:${catalina.home}/webapps/examples/-" {
//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };
//
// The permissions granted to the context WEB-INF/classes directory
// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
// };
//
// The permission granted to your JDBC driver
// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
// };
// The permission granted to the scrape taglib
// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };

Tomcat起動時にSecurityManagerを有効化

SecurityManagerでcatalina.policyファイルを使うように設定を書き直すと、 "-security"オプションを使うことで、SecurityManagerを有効にしてTomcatを起動できるようになります。

$CATALINA_HOME/bin/catalina.sh start -security    (Unix)
%CATALINA_HOME%\bin\catalina start -security      (Windows)
Tomcatのパッケージ保護の設定

Tomcat 5 から、どのTomcat内部パッケージに関して、 パッケージの宣言やアクセスができないようにするかを設定できるようになりました。 詳細は http://java.sun.com/security/seccodeguide.html をご覧下さい

警告: 初期設定のパッケージ保護を取り除くと、 セキュリティホールを作ってしまう危険があることにご留意下さい。

配布時のプロパティファイル

配布時の$CATALINA_HOME/conf/catalina.propertiesファイルは以下のようになっています。

  
#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,
org.apache.jasper.
#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageDefinition unless the
# corresponding RuntimePermission ("defineClassInPackage."+package) has
# been granted.
#
# by default, no packages are restricted for definition, and none of
# the class loaders supplied with the JDK call checkPackageDefinition.
#
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,
org.apache.tomcat.,org.apache.jasper.

catalina.propertiesファイルをSecurityManagerで使うように設定を書き直した場合は、 Tomcatの再起動を忘れないようにして下さい。

困ったときは

作成したWebアプリケーションが、必要なアクセス権がないため禁止されている操作の実行をしようとすると、 SecurityManagerが不正アクセスを検知した時点で、 AccessControlExceptionSecurityExceptionを発生させます。 どのパーミッションが抜けているかデバッグするのは難しいかもしれませんが、 例えば実行中に行なわれるセキュリティ判定に関するすべてのデバッグ情報を出力するよう設定するという方法があります。 これはTomcatを起動する前にシステムプロパティを設定することで有効になります。 一番簡単なのは、CATALINA_OPTS環境変数を使った設定です。 Tomcatを起動する前に以下のコマンドを実行して下さい。

export CATALINA_OPTS=-Djava.security.debug=all    (Unix)
set CATALINA_OPTS=-Djava.security.debug=all       (Windows)

WARNING - これはメガバイト級の出力をはきだします。 しかしながら、"FAILD"をキーワードにして検索してどのパーミッションがチェックされていたかを特定することで問題を追跡するのに役立ちます。 ここで指定可能な他のオプションに関する詳細は、Javaのセキュリティ関連文書をご覧ください。


[訳注: この文書は小山博史が翻訳し、 高橋 達男が校正しました。 日本語訳に対するコメントがあれば、report@jajakarta.orgに送って下さい。]
Copyright © 1999-2003, Apache Software Foundation