# プロになるためのWeb技術入門(LESSON6以降) ## LESSON6 Webアプリケーションを効率よく開発するための仕組み ### 6.1 サーブレット・JSPだけではいけないのか サーブレット・JSPは、JavaコードとHTML形式のコードを互いに埋め合わせることができる仕組みとして注目された。 だが、複雑なアプリケーションになると、サーブレットやJSPを単独で利用した場合に、埋め合わせが多くなり見にくくなる問題が生じた。 そこで、基本的には**サーブレットはJavaコード、JSPはHTMLメインに特化し、両者を常に組み合わせて用いることで、最低限の埋め合わせで済む形**がとられることになった。 ### 6.2 サーブレット・JSPでログイン処理を実現する LESSON4で使用したピザ注文のアプリを例に、サーブレット・JSPを利用した処理を記述する。 1. **リクエストパラメータ**を取得する。:HTMLフォームから、リクエストパラメータを取得する。なお、リクエストパラメータは読み取り専用で、値を直接改変することはできない。 2. パラメータの値を基に適切な処理を行う。:主な処理はDBへの問い合わせ、条件指定など。 3. 次の画面に送る情報を、**リクエストスコープ**に格納する。:**リクエストスコープ**は、**レスポンスを返すまで内容を保持する**もので、セッションよりも**スコープ範囲が短い。** リクエストスコープを用いると、セッションよりも短い間隔でメモリを解放できる。制御はアプリケーションサーバ内で行う。 4. 次の画面に**フォワード**する。:リダイレクトとは異なり、アプリケーションサーバ内で画面遷移を行うため、1つのリクエスト内で画面遷移が行える。 ### 6.3 Webアプリケーションのアーキテクチャ #### 6.3.1 ロジックとデザインの分離 サーブレット・JSPは、**サーブレットがロジックを、JSPがデザインを担当している。両者を分離することで、品質や効率の向上が見込める。** ここではロジックとデザインを分離する形をとった。このような、ソフトウェア全体の設計スタイルや全体構造を**アーキテクチャ**という。 #### 6.3.2 IPOとMVCアーキテクチャ * IPO:Webアプリケーションのリクエストに対する処理を、3つの過程に分けたもの。いずれもこの順番で処理が実行される。 * Input(入力):リクエストパラメータの取得など。 * Process(処理):DBアクセスや計算・変換処理など。 * Output(出力):フォワードやリダイレクト等 * MVCモデル:画面遷移や情報の流れに注目したアーキテクチャ。 * Model:処理及びその情報の保持を担当。情報を格納するクラスやDAO等。 * View:処理結果の画面表示を担当。JSP全般。 * Controller:入力およびモデル・ビューの呼び出しを担当。サーブレット全般。 ### 6.4 フレームワークによるアーキテクチャの実現 **フレームワーク**とは、アーキテクチャを具現化し、**共通様式として利用できる枠組み**のことである。 フレームワークをベースとした、様々な応用が可能となる。 #### 6.4.1 StrutsによるMVCモデルの実現 **Struts**は、Apacheが開発したMVCモデルのフレームワークであり、Webアプリケーションフレームワークのデファクトスタンダードとなっている。 * Strutsの特徴 * コントローラーは**アクションサーブレット**で処理する。 * アクションサーブレットは、**リクエストプロセッサ**を呼び出す。 * リクエストプロセッサは、strut-config.xmlに従い、**アクション**を呼び出しモデルに処理を転送する。**ユーザはstrut-config.xmlにアクションを書くだけで良い。** * リクエストプロセッサは、アクション実行前にアクションフォームBeanにアクションを記述し、参照しやすくする。→リクエストパラメータを取り出す必要が無くなる。 * リクエストプロセッサは、モデルからの結果を基に、適切な場所へとフォワードする。 * HTML、JSPではカスタムタグを利用する。 #### 6.4.2 ビジネスロジックとコントローラー **ビジネスロジック**とは、画面遷移やパラメータの受け渡しとは関係のない、内部的な計算や判定処理のことである。ビジネスロジックはMVCモデルでは**モデル**に相当する。コントローラー内には画面遷移やパラメータ処理を記述し、**ビジネスロジック等のモデルとは切り離すべきである。** ### 6.5 レイヤパターンによるデータアクセス層の分離 Strutsでは、モデルの作り方は既定していなかった。 ここでは、ビジネスロジックからデータベースへのアクセスを行う。 #### 6.5.1 JavaのDBアクセス JavaではJDBCというAPIによってデータベースへのアクセスを行う。 また、データベースへの接続はJNDI(Java Naming and Directory Interface)というAPIを利用する。 #### 6.5.2 レイヤパターンによるデータアクセス層の分離 **Layers**というアーキテクチャパターンでは、上位レイヤーが下位レイヤーの提供する機能を利用することで、各レイヤの作りを単純化している。 **各レイヤは自身と一つ下のレイヤのみに依存**し、上位レイヤや二つ以上下のレイヤの構造に関係なく動作する仕組みとなっている。 #### 6.5.3 WebアプリケーションのレイヤパターンとDAO Webアプリケーションのレイヤパターンは、**アプリケーション層(ビューとコントローラー)→ビジネスロジック層(モデル)→データアクセス層(モデル)** の3レイヤ形式になっている。 中でも**データアクセス機能のみを切り離し、データアクセス層の役割を担うDAO**は、データベーステーブルごとに作成し、テーブルに対する処理をそれぞれメソッドとして持つのが一般的である。 ### 6.6 O/Rマッピングフレームワークによるデータアクセス層の実現 オブジェクト指向のJavaと、RDBMSを用いたデータベースとの関係には、大きな欠点がある。同一データであっても、オブジェクト指向で利用する表現と、RDBMSでの表現とでは乖離が生じてしまう。こうした表現の違いを「**インピータンス・ミスマッチ**」と言う。 そこでこのインピータンス・ミスマッチを解消するフレームワークが**O/Rマッピング**である。 #### 6.6.1 O/Rマッピングの実際 **iBATIS**は、DAOでO/Rマッピングを適用するフレームワークの1つである。 このフレームワークでは、事前にSQLマップファイルを設定しておくことで、**RDBMSのデータをオブジェクトの形式へと自動的に変換する。** こうすることで、**インピータンスミスマッチを防ぎ、ミスの防止にも役立つ。** ### 6.7 フレームワーク利用のメリット・デメリット #### 6.7.1 フレームワーク利用のメリット * **設計・開発工数の削減**:あらかじめ決められたフレームワークを利用すれば工数は短縮化できる。 * **品質の向上**:既存のフレームワークはミスが無く柔軟性が高いため、コードが削減でき品質向上にも寄与する。 * **テスト工数の削減**:フレームワーク部分はテスト不要のため、工数が削減できる。 #### 6.7.2 フレームワーク利用のデメリット * **学習コストの増大**:フレームワークを使いこなしたり、そもそも知らない状態から利用するには、学習のコストが必要である。 * **フレームワークに合わせる**:フレームワークに合わせた設計やテスト手法を書く必要がある。 * **設計における自由度の低下**:フレームワークの共通認識を超えてしまうと、実現が難しい。 * **長期的な技術力の低下**:フレームワークの多くはブラックボックス化されており、頼りすぎると知識が身につかない。 ## LESSON7 セキュリティを確保するための仕組み ### 7.1 なぜセキュリティを確保しなければならないのか #### Webアプリケーションが守るべきセキュリティ * 第三者への情報流出を防ぐ(機密性):第三者に顧客情報が流出してしまうと、情報改竄やサイバー攻撃に発展する恐れがあり、企業の信頼失墜に繋がる。 * 第三者による情報の改竄を防ぐ(完全性):情報の改竄が行われると、意図しない情報の発信や、マルウェアを感染させるサイトへの誘導などが行われる可能性がある。 * 適切な権限を持った人間が適切な情報を利用できる(可用性):ログイン情報などが流出すれば、権限のない者が不正にサーバを操作する可能性がある。 ### 7.2 代表的なWebアプリケーションの攻撃手法とその対策 #### 7.2.1 SQLインジェクション SQL文として意味をなす文字列を意図して入力することで、開発者が意図しない不正な操作を行うSQL文を完成させ、機密情報を盗む手口である。 HTMLフォームからの文字列が直接SQL文に反映されるため、SQL文として成立する意図的なコードを入力すると、不正なSQL文が完成してしまう。 対策としては * 入力値を半角英数字のみにし、「'」などの記号を排除する。 * **プリペアードステートメント**の利用 SQL文を事前に登録しておき、後からパラメーターだけを動的に割り当てる形をとる。 #### 7.2.2 クロスサイトスクリプティング メールの添付ファイルや移転先リンクなどのURLから誘導サイトを開かせる。誘導サイトには悪意のあるJavaScriptコードが埋め込まれており、このサイトで入力した情報が盗み取られる仕組みとなっている。 これは、入力した文字列がそのままHTMLに出力に表示される場合に起こる。こうした脆弱性を持つサイトは攻撃の踏み台になりやすい。 対策としては * **サニタイジング**:入力された文字列を直接HTMLに出力されないよう、特殊文字を文字参照(&lt, &gtなど)に置き換えて「無害化」を行う。 #### 7.2.3 セッションハイジャック セッションIDを第三者が盗み取り、セッションを乗っ取る手口である。本来の利用者になりすまし不正な購入を行ったり、サイトに登録されている個人情報の流出が起きる可能性がある。 セッションIDの盗み取りは、クロスサイトスクリプティングの手口が利用されることが多い。 対策としては * サニタイジング(クロスサイトスクリプティング対策) * 通信経路の暗号化:**SSL(Secure Socket Layer)** を利用する。これを利用したサイトはhttpsから始まる。 * セッションIDのタイムアウト値の変更:タイムアウト値を出来る限り短くすることが大切。 * セッションIDのランダム化 #### 7.2.4 クロスサイトリクエストフォージェリ クロスサイトスクリプティング同様にURLから攻撃サイトを開かせる。攻撃サイトはHTMLが読み込まれると同時に悪意のあるJavaScriptが実行される仕組みとなっている。たとえログインが必要なサイトでも、既にログインされていれば攻撃可能となる。URLを開くと即座に攻撃する点がクロスサイトスクリプティングよりも悪質である。 原因はクッキーの仕組みにあり、一度クッキーを受け取ったブラウザは無効になるまで同じWebサイトにクッキーを送り続けてしまうため、不正なサブミットを許してしまう。 対策として * **ワンタイムトークン**の利用:サーバが最初のレスポンスで、**ランダムに生成されたワンタイムトークンを、hiddenパラメータに入力する。** 2回目のリクエストであるサブミット時にはこのワンタイムトークンも同時に送信される。サーバはワンタイムトークンを生成時のものと照合することで、**不正なサブミットを排除できる。** #### 7.2.5 強制ブラウズ URLの直接入力や、お気に入り登録したURLからのアクセスにより、本来表示されるべきではない画面を表示させる手口である。ログインしなければ見れないサイトが閲覧できてしまう可能性がある。 対策としては * ログインの有無を確認し、ログインの無いアクセスは排除する仕組みを設ける。(セッションなど) #### 7.2.6 ディレクトリトラバーサル リクエストで渡された文字列を用いてシステム内のファイルを表示するアプリケーションで発生する。 ディレクトリを強制的にルートディレクトリに戻し、そこから機密情報のあるディレクトリへのパスをリクエストとして入力することで、本来見られないディレクトリを閲覧できるようにする手口である。 対策としては * △ 予め.htmlなどの拡張子を固定化しておく。:¥0(文字列の終端を表す)によって以降の文字が排除される「ヌルバイト」攻撃を受ける可能性がある。 * ○ サニタイジング * ◎ パラメーターをファイル名として使用しない #### 7.2.7 セキュリティーに役立つ技術1:ハッシュ関数 公開鍵暗号方式やディジタル署名に利用されている、入力値に応じたメッセージダイジェストを作成する関数である。メリットは以下の通り。 * メッセージダイジェストの衝突(コリジョン)が非常に小さい。 * 情報改竄を発見できる。 * 推測不可能な文字列(ワンタイムトークン等)を作成できる。 * パスワードの代わりにメッセージダイジェストを保存できる。 #### 7.2.8 セキュリティーに役立つ技術2:Digest認証 ハッシュ関数によってメッセージダイジェストに変換し、ブラウザに入力した情報が暗号化された状態でやりとりできるようにする認証方式のこと。⇄BASIC認証 ### 7.3 設計実装ミスに起因する誤動作とセキュリティ問題を防ぐための対策 #### 7.3.1 戻るボタンとキャッシュ 戻るボタンは、ブラウザバックを行える便利な機能であるが、「キャッシュ」を利用した静的な過去ページの保存は、セッションで状態を管理している場合に問題となる。例えば購入完了画面から1画面戻ると、再度購入可能となってしまう恐れがある。 対策としては * ブラウザのキャッシュの無効化:HTTPレスポンスにCathe-Controlヘッダを設定し、no-store(保存禁止), no-catche(無断使用禁止), must-revalidade(コンテンツ有効の問い合わせを行う)の指示をそれぞれ入力する。 * 戻るボタンの無効化 * ワンタイムトークンの利用 #### 7.3.2 ダブルサブミット対策 処理に時間がかかっている場合、人はサブミットするボタンを何重にも押ししがちであるが、注文画面などの場合、意図せず繰り返し購入などが起きてしまう可能性がある問題のこと。 対策としては * JavaScriptによる対策:二重のサブミットに対し、2回目以降を処理なしとする技術。 * ワンタイムトークンの利用 #### 7.3.3 その他の注意点 * hiddenパラメータの注意点:hiddenパラメータは、リクエストをまたいだ情報の受け渡しができるが、その情報はソースを表示すれば簡単に覗けてしまう。第三者がこのパラメータを書き換えてしまえるセキュリティホールになりがちな部分である。→ワンタイムトークンの利用 * デバック情報を出力させない:開発環境では、エラーレポートメッセージは有用であるが、本番環境でエラーレポートを出してしまうとソースなどの内部構造が知られてしまう。エラー出力の処理方針を決めておくことが重要である。 * グローバル変数に情報を持たせない:機密情報を誤ってグローバル変数に持たせないように配慮しなければならない。 ###### tags: `読書`