JAVAセキュリティメカニズムのメモ
セキュリティマネージャとポリシーの設定
★ 関連記事あります:
自作Javaアプリにサンドボックスで動くアドインの仕組みを作る方法 (2018/6/12追記)
- System.getSecurityManager()がnullの場合、セキュリティメカニズムは機能しない。つまり、どのようなセキュリティポリシーであれ、それは全く検証されず全権で動作する。*1
- 一部でもセキュリティメカニズムを使いたい場合は、セキュリティマネージャを有効にする必要がある。
- システムプロパティで「-Djava.security.manager」のように指定するか、
- System.setSecurityManager(new SecurityManager());と明示的にコードで指定するか、いずれかが必要である。
- SecurityManagerクラスはほとんどの場合、単にAccessControllerへの委譲である。特別な理由がないかぎりオーバーライドする必要はない。
- セキュリティポリシーが有効になると、セキュリティ変更のための権限が検査されるようになるため、SecurityManagerを設定しセキュリティポリシーが機能する前に、セキュリティポリシーを設定しておく必要がある。
- policyファイルの構文: http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/guide/security/PolicyFiles.html#PropertyExp
- セキュリティポリシーはPolicyクラスによって保持される。
- ポリシーは、コードソースに対するパーミッションコレクションの集合である。
- 全てのパーミッションは許可を示す。拒否を示すことはできない。権限が存在しないことが拒否を表す。全権があることを示すには、AllPermissionクラスを用いる。
コードソース(Codesource)の役割
- すべてのクラスはコードソースをもっている。
- コードソースは、クラスの実体が置かれているロケーションと、そのコードの署名をもっている。ロケーションは、ローカルシステム上のアプリケーションであればファイルシステムの位置を表すURLであり、それが署名付きJARであれば、それが署名も保持する。(署名がなければnull)。このペアがコードソースである。
- 実行中のクラスのコードソースは、Class#getProtectionDomain()からProtectionDomain#getCodeSource()で取得可能である。
- コードソースに対するパーミッションコレクションのペアがプロテクションドメイン(ProtectionDomain)である。
- セキュリティポリシーでは、そのコードソースに対して権限を割り当てる。
- つまり、明示的に指定された特定の場所にあるコードのみが特定の権限をもち、それに該当しない場合は、すべてサンドボックス上で動作する。
- パーミッションの検査は、現在実行されている呼び出し履歴の中の、すべてのコードソースで許可される場合のみ許可される。いいかえると、呼び出し履歴の中の、もっとも低い権限で実行される。
特権(AccessController.doPrivileged)の意味
- 権限の低いレベルのコードソースが、権限の高いレベルのコードソースを呼び出した場合には、呼び出し履歴の規則によって、高いレベルのコードソースであっても権限は低いほうに限定される。
- 低いレベルから高いレベルのコードソースが呼び出された場合でも、そのコードソースがもっている権限を行使したい場合に「特権」を行使する。つまり、呼び出し元がどうであれ、本来、自分がもっている権限で実行したい場合が「特権」の意味である。
- つまり、ライブラリなど外部から利用される可能性があるコードにおいて、そのコードがセキュリティ上の権限を必要とする操作を行う場合には、特権コードとして実行するように記述しておかないと、実行時にセキュリティが足りない事態になる可能性がある。
- 逆に特権を行為する特別な意図がなければ、単に特権を明示しなければ最小限の権限で動作できる。
- 特権を指定しても、本来、そのコードソースが許可されている以上の権限は行使できない。
- つまり、ライブラリなど外部から利用される可能性があるコードにおいて、そのコードがセキュリティ上の権限を必要とする操作を行う場合には、特権コードとして実行するように記述しておかないと、実行時にセキュリティが足りない事態になる可能性がある。