投稿

1月20日(木)3、4コマ目

イメージ
今日、やったこと フィルター(javax.servlet.Filter)を使う 課題 今日のホワイトボード 非認証ユーザーはログインページしか表示しない 非認証ユーザーが認証済みユーザーが利用するページを直接リクエストした場合、強制的にログインページを表示するようにしたい。 図 非認証ユーザーにはユーザー情報ページは表示しない そもそもクライアントがアクセスできるのは WEB-INF以下は直接アクセスNG。サーブレットからフォワードして表示。 図 WEB-INF以下はクライアントから直接アクセスできない フィルター 各サーブレット、JSPで認証済みか否かをチェックすると、大量にある場合、非常にめんどくさい。そこで、フィルタを使えば、一か所でチェックができる。 図 フィルターで認証済みかチェック フィルターの例 課題 シーケンスについて 忘れていると思い、ちょこっと説明。 図 シーケンスについて   締め切りは1月27日(木)の4コマ目終了時。

1月17日(月)3、4コマ目

イメージ
今日、やったこと 入力チェック(HTML) エラーページ 入力内容の無害化(サニタイジング) セッションオブジェクトについて Cookieとセッション 今日のホワイトボード 入力チェック(HTML) HTML5には以下の入力チェック機能が追加されている。 type属性に応じた入力値の制約 required属性で入力必須制約 pattern属性で入力値のパターンによる制約 min属性、max属性で入力値の範囲の制約 maxlength属性で入力値の長さを制約 詳細は各自調べてください。 エラーページ いままでは実行時例外に対する処理をしていなかったため、エラー発生時にはスタックトレース画面が出力されていた。これはセキュリティ的に問題あり(サーバーのバージョンのようなサーバー環境がわかってしまう)のため、実行時例外発生時にはエラーページを表示するようにしたい。 設定ファイルweb.xmlでエラー毎のエラーページの設定ができる。 図 エラーページ 入力内容の無害化(サニタイジング) ユーザーの入力内容をそのまま出力すると問題が発生するケースがある。 例えば、HTMLのタグが入力された場合、そのまま出力するとWebブラウザはタグとして表示してしまう。 これを防ぐため、入力内容を取得するときや出力するときに 無害化(サニタイジング) を行う必要がある。 無害化(サニタイジング)は結構めんどくさいので、ライブラリを使ってください。 授業では「Apache common text」のStringEscapteUtilsクラスを利用しました。 「Apache common lang」にも同名のクラスがあるが、こちらは現在非推奨扱い。 図 無害化(サニタイジング) 作成中のアプリケーションを下図のように改造。 認証成功時はユーザー情報ページを表示する。 図 改造 セッションオブジェクト サーバーのセッションオブジェクトはクライアント毎に個別に用意される。 各セッションオブジェクトにはセッションIDが付与されている。クライアントにもセッションIDが付与され、リクエストごとにサーバーに送信することで、サーバーはクライアントとセッションオブジェクトを紐づけている。 サーバーとクライアント間でのセッションIDのやり取りの際、盗聴されるとセッションIDが漏洩してしまい、最悪セッションハイジャッ...

1月13日(木)3、4コマ目

イメージ
今日、やったこと バッファオーバー確認テスト 安全なWebアプリ(入力チェック) 今日のホワイトボード 入力チェック「なぜ必要?」 基本的には入力内容が仕様に合うかどうかをチェックする。 入力チェックをする目的は単に「数値入力用フォームに文字が入力されたか」をチェックするだけではなく、 セキュリティ的な問題を発生させない目的もある 。 図 入力チェック「なぜ必要?」 入力チェック「どこで、どうやって」 サーバー側、クライアント側の両方で行うことが望ましい。 〇クライアント側 HTML5の<input>タグや<select>タグにはチェック機能がある。 JavaScriptも使える。ライブラリもある。 〇サーバー側 基本的にString型のデータをチェックすることになる。(getParameter()の戻り値はString) JDKのjava.lang.Stringクラスのメソッドだけではちょっとめんどくさい。 「Apache Commons Lang」ライブラリのStringUtilsクラスが便利。 ただし、ライブラリをプロジェクトに追加する必要あり(WEB-INF/lib以下にjarファイルをコピー) 図 入力チェック「どこで、どうやって」 入力チェック「パターンマッチング」 電話番号やメールアドレスはパターンマッチングでチェック。 パターンの表現には正規表現を使う。 図 正規表現 ASCII文字コード表を見ると、数字やアルファベットは連続して割り当てられている。そのため、[a-z]の範囲指定でアルファベット小文字を表現できる。 正規表現を使って文字列のパターンマッチングを行うにはStringクラスのmatches()メソッドを利用する。 パスワード要件チェック パスワード要件は  4文字以上の英数字、記号  。 正規表現で表すと以下のようになる。 図 パスワード要件を正規表現で表す  

1月11日(火)1、2コマ目

イメージ
今日の予習 パスワードのハッシュ化 パスワードは平文のままでDBに保存すると、漏洩した際に被害が大きい。もし漏洩しても推測困難にするためにハッシュ化して保存するのが一般的。 ハッシュ化するためのPasswordUtilクラスをあげておきます。 PasswordUtil.java 今日、やったこと パスワードのハッシュ化 今日のホワイトボード 今まで、認証に使うパスワードをデータベースに平文で保存していました。が、データベースが漏洩した場合、パスワード情報も漏洩します。データベースが漏洩してもパスワードはすぐにはわからないようにするためにハッシュ化して保存するのが一般的です。 ユーザー認証 認証に使える情報は「本人しか持っていないモノ」、「本人しか知らないモノ」。 これらの情報が漏洩すると認証システムの崩壊になる。 図 認証に使う情報 今までは便宜上データベースにはパスワードを平文で保存していた。 が、これは危険なため、ハッシュ化して保存する。 図 今までのダメなところ ハッシュ化 元データをハッシュ関数を使ってハッシュ値を求める。 暗号化と異なるのは不可逆性。 ハッシュ値を元データに戻すことは困難。暗号文を元データに戻すことは可能。 図 ハッシュ化 ソルト ハッシュ化する際、より推測困難なハッシュ値にするために、ソルトを使ってデータ長を増やす。さらにハッシュ化する回数を増やす(ストレッチング)。 図 ソルト 認証のながれ データベースにはハッシュ化されたパスワードとハッシュ化する際に利用したソルトが格納されている。 認証の流れは下図のようになる。 図 認証処理のながれ 次回は バッファーオーバーフローのテストをします。  

1月6日(木)3、4コマ目

イメージ
今日、やったこと バッファオーバーフローでリターンアドレス書き換え 今日のホワイトボード プログラムを実行すると コンパイルで出力された実行ファイル(実行命令のリスト)がメモリ上のコード領域にロードされ、命令が順番に実行される。 図 コード領域に実行ファイルがロードされる 関数を呼び出すと コード領域にロードされた関数の命令リストへジャンプして関数を実行する。 関数実行後、呼び出し元に戻る。コード領域のどこに戻るかが、スタック上に書き込まれている。 このスタック領域の戻るべきアドレスをリターンアドレスと呼び、関数実行時に呼び出し元がスタック領域に書き込んでいる。 図 関数呼び出し時にスタック領域に書き込まれるデータ サンプルプログラムを確認 main()関数からcheck()関数を呼び出すときのメモリの状態をデバッガで確認。 ①コード領域のmain()関数をチェック 逆アセンブルすると、check()関数を呼び出す箇所がわかる。 図 main()を逆アセンブルした callqでcheck()関数を呼び出し、 0x00・・004007a5 番地に戻ってくる。 この 0x00・・004007a5 番地をリターンアドレスとしてスタック上に書き込む。 図 メモリ上のイメージ ②リターンアドレスが書き込まれる位置を確認 ブレークポイントで一時停止して確認すると、pass_buffの先頭から40バイト離れたところにリターンアドレスが書き込まれている。 図 デバッガでメモリ確認 図 メモリのイメージ ③リターンアドレスを上書きする このプログラムにはバッファオーバーフローの脆弱性があるため、リターンアドレスを上書きする。 上書きするアドレスはif()の条件成立時に実行するprintf()。 図 リターンアドレス書き換え済み C言語は危険 strcpy()以外にもコピー先のサイズに関係なくコピーする関数がある。 上限バイト数が指定できる関数を利用すること。 get -> fgets sprintf -> snprintf strcat -> strncat strcpy -> strncpy vsprintf -> vsnprintf サンプル...

1月5日(水)1、3コマ目

イメージ
今日、やったこと バッファオーバーフロー 今日のホワイトボード バッファオーバーフローとは バッファオーバーランとも呼ばれる。 確保済みメモリサイズを超えたサイズのデータをコピーして、未確保部分を上書きすること。  図 バッファオーバーフロー 実は、コンピュータシステムの重大インシデントの要因ナンバーワン(と思われる)がバッファオーバーフロー。C言語特有の「メモリ操作が簡単にできる」+「メモリ保護がない」から簡単に発生する。いやらしいのは発生するパターンが限定されるケースが多いこと。(再現性が高くない) メモリは 以下の3つのエリアに分けて使われる。 図 メモリ上のエリア 名前と利用目的をおさえておいてください。 サンプルプログラムをデバッガで確認 デバッガでサンプルプログラム実行時のメモリの状態を確認する。 メモリ番地および中身の確認にはxコマンドを使う。 図 xコマンドで変数auth_flagのメモリエリアをチェック サンプルプログラムについて (一応)認証を行うプログラム。 コマンドライン引数にて、認証に使うパスワードを指定して実行。 なお、認証OKなパスワードは「SamplePassword」。 しかしながら、パスワード「aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa」(aを30個)を指定すると、認証OKとなる。 原因はバッファオーバーフローによるメモリ破壊。実際にメモリがどうなっているかをデバッガを使って確認してみる。 デバッガで確認(正常系の場合) 引数に認証が成功する「SamplePassword」を指定して実行。 バッファオーバーフローが発生するstrcpy()の前後にブレークポイントを設定してデバッガ上で実行してみる。 〇strcpy()前 2つのローカル変数auth_flag、password_bufferを確認すると、以下のようになっている。 図 [正常系]strcpy()前 〇strcpy()後 password_bufferには「SamplePassword」がコピーされている。 auth_flagは0のまま。 図 [正常系]strcpy()後 結局、check()関数はauth_flagの値0を返すため、main()にて認証失敗と出力される。 デバッガで確認(異常系の場合) 引数になぜか認証成功になるAを30個で実行...