Section6 - 安全なwebアプリケーションのデザインと開発

6.1 セキュリティ問題に関して正確な記述もしくは命令記述

Authentication - 認証

ユーザーが本人であることを確認すること。

会員制サイトで、会員しか閲覧できないようなページがある場合、 会員は最初にログインして、会員であることを認証する必要があります。

Authorization - 許可(権限付与)

ユーザーに権限を与えること。

会員登録すると、ユーザーIDが発行され、 ユーザーIDに対して、権限が付与されます。

権限は単に、アリ、ナシだけでなく、 会員、優良会員、管理者などのように、レベル(ロール)を分けることもあります。

Data integrity - データ完全性(整合性)

データが他の第三者によって改竄されていないこと。

Auditing - 監査

セキュリティのログを正確に取ること。

Malicious code - 悪意のあるコード

故意にユーザーの不利益をもたらすコード。

悪意のあるJavaAppletや悪意のあるWebページを閲覧すると、 クッキーを盗まれたり、ウィルスに感染することがあります。

Web site attacks - Webサイトアタック

Webサイトを攻撃すること(そのままですが。。。)。

特定サイトにpingやTCP SYNを連発し、サーバを麻痺させるDoS、 セキュリティーホールをついたリクエストパラメータなどがあります。

6.2 以下のweb.xmlの要素名と構造を確認する

セキュリティーの実装方法は宣言的セキュリティーと、プログラムによるセキュリティー の2つに分けることができます。 宣言的セキュリティーは、web.xmlに宣言するだけで、セキュリティーを実装する簡単で柔軟な方法です。 プログラムによるセキュリティーは、宣言的セキュリティーだけでは対処できない、 細かいセキュリティー設定や特殊なセキュリティー実装を行いたいときに、コード中にセキュリティーを実装します。

詳しくないことに深入りして説明してもしょうがないので、 ここでは、DTD概要と簡単サンプルだけ示します。

web.xmlのセキュリティー関連のDTDをツリー表示にすると以下のようになります (見づらい。。)

  1. <security-constraint>*  セキュリティー制約
    1. <description>?
    2. <display-name>?
    3. <web-resource-collection>+  対象のWebリソース
      1. <web-resource-name>  このリソースにつける名前
      2. <description>?
      3. <url-pattern>*  Webリソースのパス
      4. <http-method>*  許可するメソッド(GET、POST、etc...)
    4. <auth-constraint>?  対象のロール
      1. <description>?
      2. <role-name>*  ロール名
    5. <user-data-constraint>?  通信の保護
      1. <description>?
      2. <transport-guarantee>  保護の方針
        (NONE、INTEGRAL、CONFIDENTIALのうち一つ)
  2. <login-config>?  認証方法を定義します。
    1. <auth-method>?  認証の種類を指定します
      (BASIC、DIGEST、FORM、CLIENT-CERTのうち一つ)
    2. <realm-name>?
    3. <form-login-config>?  フォーム認証の場合の設定
      1. <form-login-page>  ログイン画面のパス
      2. <form-error-page>  ログイン失敗画面のパス

落とし穴
*は複数指定可能。<url-pattern>や<http-method> は複数指定できる。
パスは"/"からはじまるWebアプリルートからのパス。<url-pattern>や<form-login-page>など

BASIC認証の例。

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Hoge</web-resource-name>
      <url-pattern>/jsp/secure/*</url-pattern>
    </web-resource-collection>

    <auth-constraint>
      <role-name>hoge</role-name>
    </auth-constraint>
  </security-constraint>
  
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>

FORM認証の例。

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Secure</web-resource-name>
    <url-pattern>/jsp/secure/*</url-pattern>
  </web-resource-collection>
  
  <auth-constraint>
    <role-name>hoge</role-name>
  </auth-constraint>
</security-constraint>

<login-config>
  <auth-method>FORM</auth-method>
  <form-login-config>
    <form-login-page>/jsp/login/login.jsp</form-login-page>
    <form-error-page>/jsp/login/loginFail.jsp</form-error-page>
  </form-login-config>
</login-config>

BASIC認証+SSLの例。

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Hoge</web-resource-name>
      <url-pattern>/jsp/secure/*</url-pattern>
    </web-resource-collection>

    <auth-constraint>
      <role-name>hoge</role-name>
    </auth-constraint>
    
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>

6.3 与えられた以下の認証タイプのそのメカニズムの正しい定義付けを記述

BASIC

セキュリティー制限のかかったURLにアクセスすると、 ブラウザのポップアップウィンドウで、IDとパスワードが要求されます。 入力したIDとパスワードはBASE64エンコーディング(ほぼ平文) で送信されます。

実装は簡単ですが、ブラウザのBASIC認証ウィンドウが出るため、 デザインにこだわるWebサイトだと使いたくない場合もあります。

↓HTTP BASIC認証(IE6)

DIGEST

BASIC認証と流れは同じですが、IDとパスワードが MD5で暗号化して送信されます。

BASIC認証よりセキュリティーが強固ですが、 現在、全てのブラウザで実装されいるわけではないので、 あまり利用されていません。

↓HTTP DIGEST認証(IE6)

FORM

HTMLのFORMを使い認証を行います。 セキュリティー制限のかかったURLにアクセスしようとすると、 <form-login-config>で指定したページにリダイレクトされます。

JSPやHTMLでログインページを作ります。 作成するFORMの、 ACTIONは"j_security_check"、 名前フィールド名は"j_username"、 パスワードフィールド名"j_password" でなければなりません。

↓FORMの例

<form action="j_security_check" method="POST">
  USER<input type="text" name="j_username"><br>
  PASSWORD<input type="password" name="j_password"><br>
</form>

↓FORM認証

CLIENT-CERT

クライアントに証明書を発行します。 通信はHTTPSを使いセキュリティーが強固ですが、 証明書を作ったり、発行したりする作業が必要です。

補足

プログラムによるセキュリティーで使う主なメソッド

メソッド 説明
boolean HttpServletRequest.isUserInRole(String role); 現在認証しているユーザーが指定したロールに含まれているか?
String HttpServletRequest.getRemoteUser(); 現在認証しているユーザー名を取得する。
Principal HttpServletRequest.getUserPrincipal(); 現在認証しているユーザーのプリンシパルを取得する
(Principalからはユーザー名を取るだけなので、 用途はgetRemoteUser()と同じ)。