ふみんさんの備忘録

私さんのブログです。読んだ本と行った場所の備忘録

「プロになるためのWeb技術入門」lesson6-7まで

## lesson6 Webアプリケーションを効率よく開発するための仕組み

6.1サーブレット/JSP
・ログインサーブレットの処理
→リダイレクトではなくフォワードが使われる

リダイレクト…サーバからクライアントに対して一度302を返すことで遷移先のURLを伝えクライアントからサーバへ改めてHTTPリクエストを発行している

フォワード…アプリケーションサーバの中でだけで遷移処理が行われる。そのため1回のHTTPリクエスト遷移が可能になる。

リダイレクトよりもフォワードは応答が速いため処理結果で異なるjspを表示する際などはフォワードを使用することが推奨されている。


・リクエストスコープにおける情報の受け渡し
リクエストスコープ…フォワード元とフォワード先の間でJavaのオブジェクトを共有するための仕組みである。
(→cf.リクエストパラメータ…HTTPのGET、POSTメゾットによってクライアントからWebアプリケーションに文字列として渡されるものである。受け取った値を変更することはできない。)
アプリケーションサーバから提供される仕組み。フォワードの前後でJavaオブジェクトを共有することができる。
一回のHTTPリクエストを処理する間のみ有効なため、リクエスト処理が終了するとリクエストスコープに保持されていた情報は消えてしまう。

・セッションスコープとリクエストスコープの違いに関して
セッションスコープはCookieなどの仕組みを利用し、アプリケーションサーバのメモリに保存される。
そのためセッションが増えるとメモリ不足になる。
(cf.タイムアウト→最終アクセスから一定時間経過したセッション情報をすでに使われなくなったものと判断し自動的に削除する仕組み Tomcatではデフォルト30分に設定されている)

セッションスコープでは、複数のリクエストにまたがって有効なため
ログイン状態や購入商品などユーザーがWebアプリケーションを使用している間に保持しておきたい情報を格納するのに適している。
リクエストスコープではクライアントからリクエストが届いてから、レスポンスを返す間しか有効にならない。


・コラム/URLリライティング
PHPなどではCookieが利用できない場合「PHPSESSID」というパラメータ名でリクエストのURL
にセッションIDが含められるようにformタグが自動で書き換えられサブミット時にGETパラメータとしてセッションIDが渡されるようにしている。

・Webアプリケーションのアーキテクチャ
ロジックとデザインの分離
ソフトウェアの設計スタイルとその設計に基づく全体構造を「アーキテクチャ」と呼ぶ。

cf)カスタムタグ
エラーメッセージなどを開発者が自分で用意したタグをカスタムタグと呼ぶ。

・例題Webアプリのアーキテクチャ

webアプリケーション内の細かな処理は「入力データの取り出し(Input)」「データ処理(Process)」「HTML出力準備(Output)」
という「IPO」の流れで構成されている。

例題のWebアプリは「モデル(model)」、「ビュー(view)」、「コントローラ(controller)」で構成される、「MVCモデル」である。

a)model
モデルはアプリケーションの「処理」の部分とそれにかかわる情報を保持する。
そのため、画面に対する入出力といった部分には一切関わりを持っていない。

b)view
ビューはモデルによる処理結果の画面への表示を担当する。
処理結果自体はmodelが持っているためビューがモデルから取り出してユーザに見やすいように整形した上で画面へ表示する。
あくまで画面への表示が役割であり、情報処理には関わらない

c)controller
controllerは画面からの情報入力とモデルの呼び出し及びにその結果に従ったビューの呼び出しを担当する。
controllerはユーザーがユーザが画面に入力した情報を取り出し処理を担当するmodelに渡す。
modelの処理結果によって結果を表示するviewを呼び出す。

MVCモデルに基づくことで、「ロジックとデザインの分離」を実現することができる。
ロジックーmodel
デザインーview

MVCモデルによる処理の流れ
1、Webブラウザから送信されたリクエストはまずコントローラが受け取る。
2、コントローラはリクエストからパラメータを取り出し、必要に応じてセッションからの情報を取り出す。
3、入力情報を処理するモデルを呼び出し、各パラメータを処理、格納する
4、モデルはそれらの結果をコントローラに返却する。(この際に返すのは処理結果そのものではなく、成功・失敗程度のステータスになる)
5、コントローラは受け取ったステータスから表示すべき画面を選択し、その画面を表示するためのビューを呼び出す。
6、ビューはモデルを参照し、表示すべき情報を取り出しその結果をHTMLとして出力してHTTPレスポンスとしてWebブラウザに返す。

 

フレームワークによるアーキテクチャーの実現
フレームワークとは
アーキテクチャを実現する部分は共通化し、見た目など個々のアプリケーションで異なる部分は別々に開発できるようになれば効率よくアプリケーションを開発できるようになる。
品質も保ちやすい。
この共通部品の考え方がソフトウェアにおけるフレームワークである。

cf)Struts(フレームワーク)

・レイヤーパターンによるデータアクセス層の分離

224

JavaではdbにアクセスするAPIとしてJDBCが用意されており、JDBCを使ってDBに対してSQLを発行し結果を取得する。

a)データソースの取得
WebアプリケーションがDBに接続するにはまず「JNDI」と呼ばれるAPIを利用してアプリケーションサーバからDataSourceクラスの
オブジェクトを取得する

b)コネクションの取得
DataSourceが取得できたら、getConectionメソッドを呼び出してデータベースへ接続する。データベースへの接続はConnectionクラスのオブジェクトとしてあらわされる。

c)SQLの発行
SQLを発行するにはConnectionオブジェクトのcreateStatementメソッドを呼び出してStatementオブジェクトを取得する。
引数にSQL文を指定してStatementオブジェクトのexecuteQueryメソッドを呼び出すことでSQLが発行される

d)SQL実行結果の取得
SQLの実行結果はexecuteQueryメソッドの戻り値として得られるResultSetオブジェクトから取得できる。
ResultSetオブジェクトではnextメソッドでレコードを呼び出し引数にgetXXXXメソッドを呼び出すことで各カラムの値を取り出すことができる。


・「Layers」と呼ばれるアーキテクチャーパターン
上位レイヤーが下位レイヤーの提供する機能を利用することで、各レイヤの作りを単純化していく考えである。

a)プレゼンテーション層
●コントローラー・ビューが属する
システム利用者とのインターフェースを担当するレイヤ。
Webブラウザを通してユーザからの入力を受け付けて下位のレイヤであるビジネスロジック層に渡し、その処理結果を再びWebブラウザへ表示させたりといったことを担当する

b)ビジネスロジック
●モデル
アプリケーションが実現すべき固有の処理を実行するためのレイヤ。「業務ロジック」と訳される。
ビジネスロジックは、ユーザーが入力した情報をプレゼンテーション層から受け取り、必要に応じてデータベースを利用し、処理を実行する。処理結果は、プレゼンテーション層へ返す。

c)データアクセス層(cf.インテグレーション層)
●モデル
ビジネスロジック層とデータベースの仲立ちを行うためのレイヤ。
データベースへのアクセスなど面倒な処理をビジネスロジックから切り離し、データベースへの細かなアクセス手順を意識せずとも利用できるようにする。
cf)DAOを使用する。

O/Rマッピングフレームワークによるデータアクセス層の実現
cf)
▲「iBATIS
・「インピーダンス・ミスマッチ」ーリレーショナルデータベースとオブジェクト指向の表現の違い。

フレームワーク利用におけるメリットとデメリット

●メリット
1、設計・開発工数の削減
ー優れた設計の再利用。共通で必要なデータベースアクセスなどはフレームワークの規定に沿って必要なコードを作成するだけで済む点。

2、品質の向上
ー生産性の向上から結果としての品質の向上。

3、テスト工数の削減
ー新たに作成されるコード自体がフレームワークによって減るため、テスト工数の削減につながる。

●デメリット
1、学習コストの増大

2、設計における自由度の低下
フレームワークの設計者の意図した範囲ではないことを実現しようとすると難易度が高くなってしまうことなどがある。

3、長期的な技術力の低下
フレームワークは簡単に使えるように内部をブラックボックス化してしまうために、裏側で何が行われているのか知ることができなくなる。
また開発現場で不具合が生じた場合フレームワーク起因の可能性もある。そのために開発者はフレームワークの裏側でどのようなことが行われているのか知る必要がある。

 

 


##lesson7セキュリティを確保するための仕組み 

・Webアプリケーションにおける守るべき情報セキュリティ
1、第三者への情報の流出を防ぐこと(機密性)
2、第三者による情報の改ざんを防ぐこと(完全性)
3、適切な権限を持った人間が適切な情報を利用できること(可用性)

・代表的なWebアプリケーションの攻撃手法とその対策
SQLインジェクション
Webフォームなどの入力インターフェースを利用してデータベースに発行されるSQLを開発者が意図しない形に変更すること。(cf.不正ログイン)
インターネット経由でどこからでも攻撃が可能な点
被害者が情報流出に気が付きにくい点

入力値のチェック(ex.バリデーション)
プリペアード・ステートメント
(文字列連結などでSQLを組み立てず、WHERE句など条件によって変化する部分をプレースホルダとして登録したSQLを事前に用意しあとからパラメータを割り当てる方法)

クロスサイトスクリプティングXSS
HTML内に悪意のある動作をするJavaScriptを埋め込む。クッキーの盗難やページの改ざんなどができる。セッションハイジャックなどにつながる恐れがある。

サニタイジング
(HTMLの破壊をする文字列を、無害な文字列に変換するなどの処理を行うこと。多くのプレゼンテーション層を扱うフレームワークで同様の機能を備えている。)

入力チェック(受け付ける文字列を絞る)→出力時に出力対象に応じてサニタイジングを行うのが理想。

セッションハイジャック
クライアントとサーバの間でやり取りされているセッションIDを第三者が盗み取ること。

1、XSS対策

2、通信経路の暗号化
インターネットを流れる通信は盗聴できるため、通信経路をSSLによって暗号化することが必要になる。

3、セッション・タイムアウト値の変更
利用者がログアウト処理を忘れてしまった場合、セッション・タイムアウトが発生するまでセッションIDも有効なため、セッションIDが盗まれた場合被害を受ける。
セッション・タイムアウト時間を短めに設定することでセッションIDが悪用される可能性を低くできる

4、セッションIDのランダム化
セッションはアプリケーションサーバなどによって実現されているため、開発者が自分で対策することは少ない。セッションの安全性は「セッションIDが十分大きな桁の数字の中からランダムに選択された」という事実によって支えられている。

●コラム
SSLによる通信経路の暗号化
httpsSSLで暗号化された通信である。
公開鍵暗号
→二つで一対の鍵を使う。
相手に送る暗号化用の鍵を「公開鍵」
自分で持っておく復号用の鍵を「暗号鍵」と呼ばれる。
cf)「SSLアクセラレータ」ー暗号化処理を高速実現している。

クロスサイトリクエストフォージェリCSRF
攻撃者が捏造したフォームから強制的にサブミットすることで、掲示板に意図しない書き込みをされたりする攻撃。

①フォーム表示のリクエストがアプリケーションサーバに届いた際に「ワンタイムトークン」を生成
②生成したワンタイムトークンを「hiddenパラメータ」に埋め込みフォームを表示
③サブミットされた際に、ワンタイムトークンも送られる(→これを照合し、自サーバで生成したものであればサブミットを受け入れる)

●コラム「ハッシュ関数
ハッシュ関数とは任意の長さの入力に対して「メッセージダイジェスト」と呼ばれる固定長の値を出力する関数である。
1、ハッシュ関数は入力となる情報が少しでも変化すると結果が大きく変化する
2、異なる入力に対して同じ出力がなされる「衝突」が起きにくい
3、メッセージダイジェストから元の入力を推測するのが困難

情報改ざんの発見
ワンタイムトークンなど推測不可能な文字列の生成
パスワードの保存
などに使用されている

●強制ブラウズ
webブラウザんぽアドレスバーにURLを直接入力することで本来表示されるべきではない画面を表示させる攻撃である。
ログイン状態の確認→ログイン画面の経由をどのような画面にアクセスされても可能としなければならない。
ディレクトリのファイル一覧を表示する機能が見えることもある。(ex. Apache→Indexesというアクセスが有効になっている場合など)

jsによるアドレスバー非表示(URLの確認や直接入力の禁止、ブラウザによってはjsを無効にできるため有効ではない)

ディレクトリトラバーサル
リクエストで渡された文字列を使ってシステム内のファイルを表示するアプリケーションで注意すべき(アクセスされたくない親フォルダーなどに対するアクセスを相対パスなどで可能にする)
「¥0」-ヌルバイト(¥0という文字列は文字列の終端を示すことが多いため、これが挿入されるとそれ以降の文字列が無視されてしまう)

サニタイジング
ファイルシステムのアクセス権を適切に設定する
ユーザから入力されたパラメータをファイル名として使用する設計にしない

●コラム Digest認証(ダイジェスト認証)
ハッシュ関数を利用して、ユーザー名やパスワードを直接送受信せずに実現する
(HTTP通信そのものは暗号化されないためSSL/TLSの利用が必要)

・設計/実装ミスに起因する誤作動やセキュリティ問題を防ぐために

●「戻る」ボタン対策
1、ブラウザによるキャッシュ無効化
フレームワークが提供していることも多いので一度確認する。

2、戻るボタンの無効化
jsでの無効化になるため、js自体が無効化されている場合には意味をなさない
企業内で使用するWebアプリケーションなどの場合は有効

3、ワンタイムトークンの利用
hiddenパラメータにワンタイムトークンを埋め込み、サブミットされた際に他の値と一緒に調べる

●ダブルサブミット対策
二重押下問題

1、jsによる対策
ボタンが押されたかを変数に格納し、一度目はfalseで返し二度目以降はtrueで返すなど。

2、ワンタイムトークンによる対策

●hiddenの注意点
・hiddenパラメータは任意の情報をフォームに格納することでリクエストをまたいだ情報の受け渡しを可能としている。これらはWebブラウザから容易にのぞくことができる。そのためログイン中かなどをアプリケーション上の状態を直接保持するなどはしない。

CSRF対策としてのワンタイムトークンを使用する。更新画面等を表示する際にサーバが発行するため、ワンタイムトークンが分からなければ捏造したhiddenパラメータを直接POSTし処理させることは困難になる。
使い捨て、推測困難なため 連続した攻撃に使えない・ワンタイムトークン捏造することも難しい。

デバッグ情報を出力させない
エラー情報をそのままブラウザ出力せずにログファイルなど決められた場所へ出力するなど方針を決めておく

 

 

グローバル変数に情報を持たせない
どこからでもアクセスできる可能性のある変数に格納することで想定しなかったユーザに画面を表示してしまう可能性がある

JavaのWebアプリケーション>アプリケーションサーバは「スレッド」という仕組みで複数のクライアントからリクエストが来ても同時に実行ができる。
サーブレットインスタンスはリクエストごとに生成されるのではなく、アプリケーションサーバの中で1つだけしか生成されない。
そこで表示に使用する情報などをインスタンス変数に保持していると、同時にアクセスしているほかの利用者の情報が誤って表示されてしまう。