JARファイル・マニフェストには、セキュリティと構成の情報など、JARファイルのコンテンツに関する情報が含まれています。このセクションで説明するマニフェスト属性を使用すると、ブラウザからRich Internet Application (RIA)を実行する際のセキュリティが向上します。
属性は、JARファイルが署名される前にマニフェストに追加する必要があります。JARマニフェスト・ファイルに属性を追加する方法については、Javaチュートリアルの「Modifying a Manifest File」を参照してください。
注意: これらの属性は、署名付きアプレット、Java Web Startアプリケーション、およびWebページに埋め込まれたりブラウザから起動されるJavaFXアプリケーションに適用されます。これらの属性は、スタンドアロン・アプリケーションおよび自己完結型アプリケーションでは無視されます。 |
この節の内容は以下のとおりです。
Permissions
属性は、RIAによってその実行時に要求されるアクセス権のレベルが、JARファイルの作成時に設定されたアクセス権のレベルと一致していることを検証するために使用されます。この属性はRIAのメインJARファイルのマニフェストに含まれている必要がありますが、セカンダリJARファイルおよび拡張機能にはPermissions
属性は必要ありません。この属性がメインJARファイルに存在しない場合、RIAはブロックされます。
Permissions
属性を使用すると、自身の証明書で署名されているアプリケーションが再配備されたり、異なる特権レベルで実行されたりすることを防げます。この属性は、次のいずれかの値に設定します。
sandbox
- RIAがセキュリティ・サンドボックス内で実行され、追加のアクセス権を必要としないことを示します。
all-permissions
- RIAがユーザーのシステム・リソースへのアクセスを必要とすることを示します。
JNLPを使用するJava Web Startアプリケーションおよびアプレットの場合、Permissions
属性の値は、JNLPファイルで要求されているアクセス権のレベルと一致する必要があり、アクセス権のレベルが要求されていない場合は、デフォルトのアクセス権と一致する必要があります。それ以外の場合は、エラーが表示され、RIAはブロックされます。アクセス権のレベルの要求に使用されるsecurity要素については、「Structure of the JNLP File
」を参照してください。その要素が存在しない場合、アクセス権のレベルはデフォルトでsandbox
になります。
JNLPを使用しないアプレットの場合、Permissions
属性の値は、appletタグで要求されているアクセス権のレベルと一致する必要があります。それ以外の場合は、エラーが表示され、RIAはブロックされます。appletタグにアクセス権のレベルが含まれていない場合は、Permissions
属性で設定されたアクセス権のレベルを使用して署名付きアプレットが実行されます。appletタグでアクセス権のレベルを設定する方法については、「Deploying with the Applet Tag」を参照してください。
Codebase
属性は、JARファイルのコード・ベースを特定のドメインに制限するために使用されます。この属性を使用すると、悪意のある目的でアプリケーションが別のWebサイトに再配備されることを防げます。
注意: Codebase 属性でセキュアなサーバー(HTTPS など)を指定しない場合は、コードがMan-in-the-Middle (MITM)攻撃スキームで悪用される可能性があるという多少のリスクが生じます。 |
この属性は、アプリケーションのJARファイルが置かれているドメイン名またはIPアドレスのどちらかに設定します。プロトコルおよびポート番号を含めることもできます。複数の場所を指定する場合は、それらの値を空白で区切ります。アスタリスク(*)は、ドメイン名の先頭にのみ、ワイルドカードとして使用でき、トップレベル・ドメインのみと一緒に使用することはできません(*.comなど)。次の表に、サンプル値とそれらに一致するものを示します。
表26-1 Codebase属性の有効な値
値 | 一致するもの | 一致しないもの |
---|---|---|
* |
すべてのドメイン |
|
https://*.example.com |
https://a.example.com https://a.b.example.com |
http://a.example.com http://a.b.example.com |
www.example.com |
https://www.example.com、http://www.example.com |
http://example.com http://example.net |
www.example.com:8085 |
https://www.example.com:8085、http://www.example.com:8085 |
http://www.example.com |
*.example.com |
https://a.example.com、http://a.example.com https://a.b.example.com、http://a.b.example.com https://example.com、http://example.com |
http://example.net |
127.0.0.1 |
http://127.0.0.1 http://127.0.0.1:8080 http://127.0.0.1:80 |
http://localhost |
127.0.0.1:8080 |
http://127.0.0.1:8080 |
http://127.0.0.1 http://127.0.0.1:80 |
Codebase
属性の値は、RIAに使用されるJARファイルの場所と一致する必要があります。それ以外の場合は、エラーが表示され、RIAはブロックされます。この属性が存在しない場合は、警告がJavaコンソールに書き込まれ、appletタグまたはJNLPファイルに指定されたコード・ベースが使用されます。
Application-Name
属性を使用すると、署名付きRIAのタイトルを指定できます。RIAのタイトルは、RIAを実行するための権限を求めるプロンプトが表示される際に、セキュリティ・プロンプトで使用されます。意味のあるタイトルを指定すると、RIAを信頼して実行することを決定するのに役立ちます。この値には、任意の有効な文字列を指定できます。例:
Application-Name: Hello World
RIAに無署名のJNLPファイルがある場合またはWebページのアプレット・タグで起動されている場合、Application-Name
属性を使用して、署名付きソースの有効なタイトルが表示されるようにしてください。Application-Name
属性がJARファイル・マニフェストに含まれていない場合は、警告がJavaコンソールに書き込まれ、Main-Class
属性の値が使用されます。どちらの属性もマニフェストに含まれていない場合は、セキュリティ・プロンプトに表示されるタイトルはありません。
RIAに署名付きのJNLPファイルがある場合、セキュリティ・プロンプトに表示されるタイトルは、JNLPファイルのタイトル要素から取得されます。Application-Name
属性は無視されます。
署名されていないRIAにはタイトルが表示されません。
Application-Library-Allowable-Codebase
属性は、署名付きRIAが見つかると予想される場所を識別します。この属性は、RIAのJARファイルが、RIAを起動するJNLPファイルまたはHTMLページとは異なる場所にある場合にユーザーに表示されるセキュリティ・プロンプトの「場所」フィールドにリストされる内容を決めるために使用されます。ファイルが識別された場所にない場合、RIAはブロックされます。この属性は、JARファイル、JNLPファイルおよびHTMLページが置かれているドメインに設定します。複数のドメインを指定するには、それらのドメインを空白で区切ります。例:
Application-Library-Allowable-Codebase: https://host.example.com *.samplehost.com
Application-Library-Allowable-Codebase
属性が存在し、RIAが起動される場所と一致する場合は、プロンプトの「場所」フィールドに1つのホストがリストされ、次回から表示されるプロンプトを非表示にするオプションが表示されます。この属性が存在し、ファイルがその属性で指定されていない場所からアクセスされる場合、RIAはブロックされます。この属性が存在しない場合は、JARファイルとJNLPファイルまたはHTMLページの場所に対応する複数のホストがプロンプトの「場所」フィールドにリストされます。複数のホストが表示された場合、ユーザーは「上記の発行者と場所からのアプリケーションについては、次回から表示しない」チェック・ボックスを選択できます。RIAのファイルが既知の場所からのみアクセスされるように、この属性の使用をお薦めします。
RIAのJARファイルが、RIAを起動するHTMLページと同じ場所にある場合、この属性は必要ありません。Java Web StartがダウンロードされたJNLPファイルとともに使用され、このファイルにJNLPファイルの元の場所に設定されたhref
属性が含まれない場合、この属性は必要です。ダウンロードされたJNLPファイルにhref
属性が含まれない場合、このファイルはローカル・ファイルとして扱われるため、RIAのJARファイルの場所とは一致しません。
指定できる値については、「Codebase属性」を参照してください。
Caller-Allowable-Codebase
属性は、セキュリティ・プロンプトなしでJavaScriptコードがRIAへの呼出しを行えるドメインを識別するために使用されます。この属性は、JavaScriptコードをホストするドメインに設定します。Caller-Allowable-Codebase
属性で指定されたドメインに置かれていないJavaScriptコードから呼出しが行われた場合、その呼出しはブロックされます。複数のドメインを指定するには、それらのドメインを空白で区切ります。例:
Caller-Allowable-Codebase: host.example.com 127.0.0.1
Caller-Allowable-Codebase
属性が存在しない場合、JavaScriptコードからRIAへの呼出しによってセキュリティ警告が表示され、ユーザーはその呼出しを許可するかブロックするかを選択できます。署名されていないRIAでは、RIAへのアクセスを必要とするJavaScriptコードが、RIAのメインJARファイルと同じ場所にある必要があります。それ以外の場合、ユーザーはアクセスを許可するよう求められます。セキュリティ・プロンプトは、アプレットのclassLoader
インスタンスごとに表示されます。
指定できる値については、「Codebase属性」を参照してください。単独のアスタリスク(*)または*.org
などの最上位ドメインで使用されるアスタリスクがCaller-Allowable-Codebase
属性の値として指定されている場合、JavaScriptコードからRIAへの呼出しによってセキュリティ警告が表示されます。ユーザーはその呼出しを許可するかブロックするかを選択できます。選択内容を覚えておくオプションも用意されています。選択内容を覚えておくよう選択した場合、同じソースからJavaScriptコードからの呼出しを受信したときに、同じRIAに対する警告メッセージは表示されなくなります。
Entry-Point
属性は、RIAへのエントリ・ポイントとして使用できるクラスを識別するために使用されます。エントリ・ポイントを識別することは、main()
メソッド、複数のアプレット・クラス、または複数のJavaFXアプリケーション・クラスを持つ複数のクラスがJARファイルにあるときに、認可されていないコードを実行しないようにする際に役立ちます。この属性を、RIAのエントリ・ポイントとして使用できる完全修飾クラス名に設定します。複数のクラスを指定するには、クラスを空白で区切ります。次に例を示します。
Entry-Point: apps.test.TestUI apps.test.TestCLI
JARマニフェストに署名され、JNLPファイルまたはアプリケーション記述子で指定されたmain-class
またはapplet-class
エントリ・ポイントが、Entry-Point
属性に指定されたクラスと異なる場合、RIAはブロックされます。Entry-Point
属性が存在しない場合、main()
メソッドを持つクラス、またはJARファイル内のアプレットまたはJavaFXアプリケーション・クラスは、RIAの起動に使用できます。
Trusted-Only
属性は、信頼できないクラスまたはリソースがアプレットまたはアプリケーションでロードされることを防ぐために使用されます。この属性の値はtrue
に設定します。例:
Trusted-Only: true
この属性は、特権付きのアプリケーションまたはアプレットが転用されて、信頼できないコンポーネントが追加されることを防止します。アプリケーションまたはアプレット内のクラスとリソースはすべて署名付きで、すべてのアクセス権を要求するものである必要があります。
Trusted-Library
属性は、信頼できないコンポーネントを許可するように設計されているアプリケーションとアプレットに使用されます。警告ダイアログは表示されず、アプリケーションまたはアプレットは、信頼できないクラスやリソースが含まれるJARファイルをロードできます。この属性の値はtrue
に設定します。例:
Trusted-Library: true
この属性は、特権付きのアプリケーションまたはアプレット内のコンポーネントが転用されて、信頼できないコンポーネントが追加されることを防止します。このマニフェスト属性を含むJARファイル内のクラスとリソースはすべて署名付きで、すべてのアクセス権を要求するものである必要があります。
混合コードのアプリケーションまたはアプレットでは、特権付きのクラスとリソースはすべて、Trusted-Library
属性を含むJARファイル内に含める必要があります。この属性は、特権付きJavaコードとサンドボックスJavaコード間の呼出しに使用されます。Javaコードを呼び出すJavaScriptコードが含まれている場合は、「Caller-Allowable-Codebase属性」を参照してください。
信頼できるライブラリJARはすべて、そのアプリケーション・インスタンスまたはアプレット・インスタンスに固有の個別の専用クラス・ローダー内にロードされます。このTrusted-Library
ローダーが、Web Startまたはアプレットの通常のクラス・ローダーの親になりました。元の検索順との下位互換性を保てるように、両方のローダーが協調して共通のクラス・パスを実装しています。以前のリリースと同様、JARファイルは遅延ダウンロードを使用し、要求されたクラスとリソースを見つけるため必要に応じて開かれます。
Trusted-Library
マニフェスト属性を付ける予定のJARファイル内のコードで、クラス・ローダーに依存する呼び出し(単一パラメータ版のClass.forName()
、Class.getResource()
、Class.getResourceAsStream()
、java.util.ResourceBundle.getBundle()
のいくつかのバリアントなど、直接の呼出し元が定義しているローダーを基準にして動作するすべてのメソッド)を使用している場合には、コードを若干変更しなければいけない可能性があります。変更を加える必要があるのは、Trusted-Library
でない(したがってWeb Startまたはアプレットの通常のクラス・ローダーによってロードされる) JARファイル内で、要求されたクラスやリソースが見つかる可能性がある場合だけです。
Trusted-Library
内のコードで通常のローダーを検索するには、Thread.currentThread().getContextClassLoader()
を呼び出します。ただし、getContextClassLoader()
からnull
が返される状況がまれに発生します。たとえば、ガベージ・コレクタがJREシステム・スレッドを使って、到達不可能なインスタンスのObject.finalize()
メソッドを呼び出したときに、これが発生する可能性があります。
メソッドClass.getResource()
またはClass.getResourceAsStream()
をClassLoader
の対応するメソッドに変換する必要がある場合には、これら2つのメソッドのドキュメントの説明に従って、文字列パラメータを忘れずに調整してください。元のリソース名が'/'
で始まっている場合、それは絶対名なので、先頭の'/'
を単純に削除する必要があります。それ以外の場合、getResource
呼出しのターゲットとなっていたクラス・インスタンスが、名前付きパッケージに含まれているかどうかを判別します。それが配列の場合、まずは配列のベースとなるコンポーネントの型を判別すべきです。クラスまたはコンポーネントの型のインスタンス上でClass.getName()
を呼び出します。クラス名に'.'
文字が1つでも含まれている場合、名前付きパッケージ内にそのクラスは含まれており、元のリソース名の先頭にそのパッケージ名を追加する必要があります。パッケージ名を判別するには、末尾の'.'
文字とそれ以降の文字をすべて削除します。次に、残った'.'
文字をすべて'/'
文字に置き換えます。最後に、'/'
を末尾に1つ追加したあと、元のリソース名文字列を追加します。これで、この新しい文字列を、ClassLoader
バージョンのgetResource()
またはgetResourceAsStream()
メソッドに渡すことができます。
一般に、信頼できるライブラリ内のコードが、注意深くセキュアな方法で記述されるように、またその他の点では、アプリケーションの一部であり、通常のローダーによってロードされる残りの任意のJARから、個別のクラス・ローダー・インスタンス内にロードされる互換性を保てるように、注意を払う必要があります。
Permissions
属性およびCodebase
属性は、認可されていないコードの再利用からRIAを守るために、JDK 7u25リリースで導入されました。
Permissions
属性が存在しない場合は、攻撃者が、証明書で署名されているアプリケーションを再デプロイしたり、異なる特権レベルでそのアプリケーションを実行したりすることで、ユーザーにつけ込む可能性があります。
Codebase
属性でセキュアなサーバー(HTTPSなど)を指定しない場合は、コードがMan-in-the-Middle (MITM)攻撃スキームで悪用される可能性があるという多少のリスクが生じます。
次のコード例は、セキュリティ・サンドボックス内で実行され、https://example.com
からアクセスされると予想されるRIAがある場合に、マニフェストに追加する属性を示します。
Permissions: sandbox Codebase: https://example.com
そのRIAがexample.backup.com:8080
からも利用できる場合は、Codebase
属性で両方のドメインを含めます。
Codebase: https://example.com example.backup.com:8080
マニフェスト属性を使用して信頼できないコードからの呼出しを管理する方法については、第27章「特権付きコードとサンドボックス・コードの混合」を参照してください。
JARマニフェスト・ファイルに属性を追加する方法については、Javaチュートリアルの「Modifying a Manifest File」を参照してください。