TERASOLUNA 5.x学習(4.2 例外ハンドリング)

ガイドライン

4.2. 例外ハンドリング — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.2.0.RELEASE documentation

学習のポイント

  • 細部にとらわれないこと
  • 分析や解釈の罠にはまらないこと
  • ストーリーを作ること
    • どんな利用状況がある?
    • 誰向けの説明?誰向けのシステム?
    • 口頭で説明できる?
  • 構造の理由を腹落ちさせること
    • セキュリティ
    • 開発生産性
  • 動作イメージを腹落ちさせること
  • メタファを作ること
  • トライアンドエラーできる環境を作ること
  • 情報を整理しようとするな(しすぎるな)
    • けっこう自分の悪いクセではある
    • 情報はどんどんフローで流す
    • かけ流しながら都度考える
    • かけ流しなら書き流すとよい
    • 最後の最後で整理すればよい

課題

  • ServletとControllerの関係性について
  • 例外の発生原因、発生場所、対処法
  • システム例外、予期しないシステム例外、致命的なエラーの線引

書き流し

  • ビジネス例外、システム例外、フレームワーク例外、
  • 例外のスロー、ハンドリング、try-catch、@ExceptionHandler、HandlerExceptionResolver、<mvc:annotation-driven>、SystemExceptionResolver、error-page、ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver、自動的に登録されるHandlerExceptionResolver、@ControllerAdviceアノテーションをクラスにつけて@ExceptionHandlerアノテーションをメソッドにつける、サーブレット内のすべてのController、ビジネス例外、ライブラリ例外、システム例外、致命的なエラー、フレームワーク例外
  • 説明が細かすぎて逆に見通しが悪くなっている
  • 説明が無機質すぎて心に残らない。例外のヤバみが伝わってこない
  • システム例外、予期しないシステム例外、致命的エラーの線引がいまいちわからない
  • ハンドリング単位:リクエスト、ユースケースサーブレット、Webアプリ
  • プロジェクトに参加したときに、「一人でなんでもできる」のではなく、メンバや顧客と議論できるだけの「語彙」と「手を動かした経験」「さくっと検証できるスピード感」が大事になってくる
  • 例外の処理方法はある程度システマチックにできるはずだから、慣れてくると実装するのが楽しくなっていく予感はある
  • このガイドライン、書き下していっている印象あるけど、網羅性ってどう担保しているのだろう
  • ガイドラインの読み方=網羅性を拾い上げていく作業?

TERASOLUNA 5.x学習(4.1 入力チェック)

ガイドライン

学習のポイント

  • 細部にとらわれないこと
  • 分析や解釈の罠にはまらないこと
  • ストーリーを作ること
    • どんな利用状況がある?
    • 誰向けの説明?誰向けのシステム?
    • 口頭で説明できる?
  • 構造の理由を腹落ちさせること
    • セキュリティ
    • 開発生産性
  • 動作イメージを腹落ちさせること
  • メタファを作ること
  • トライアンドエラーできる環境を作ること
  • 情報を整理しようとするな(しすぎるな)
    • けっこう自分の悪いクセではある
    • 情報はどんどんフローで流す
    • かけ流しながら都度考える
    • かけ流しなら書き流すとよい
    • 最後の最後で整理すればよい

課題

書き流し

Webについて

Tomcatについて

  • Tomcat Webアプリケーションマネージャ(Web画面でデプロイが可能になる)を有効にするには、conf/tomcat-users.xmlに以下を追記する。

  • Tomcatでearファイルをデプロイする方法

    • たぶん無理?Jbossなら…

WAS(WebSphere Application Server)について

  • windows版)起動前に、プロファイルを作成する。
  • windows版)IHS管理サーバは別途コマンドラインで起動する。

    "C:\Program Files (x86)\IBM\HTTPServer\bin\httpd.exe" -f "C:\ProgramFiles (x86)\IBM\HTTPServer\conf\admin.conf"

    • HIS管理サーバを起動しておかないと、WAS管理コンソールから起動停止できない。
    • adminconfの「@@AdminPort@@」を「8008」に書き換える。
    • admin.confのパスは絶対パスじゃないと駄目っぽい。
  • Linux版)IIM(IBM Installation Manager)でIBMリポジトリを認証するコマンドは以下、なのだがうまくいかない(ブラウザでurl開いてもエラーになるし)。

    ./imutilsc saveCredential -userName hogeuserid -userPassword hogepass -url http://www.ibm.com/software/repositorymanager/entitled/repository.xml

    • IBM ID」でリポジトリを認証する(はず)。
      →上の例だとユーザIDが「hogeuserid」、パスワードが「hogepass」

Strutsの脆弱性について

  • Struts脆弱性の根本原因には、ClassLoaderを直接操作できてしまう仕様に起因するものが多い。

    • 攻撃手法として、クライアントからの不正なリクエストが使われる。すなわち、脆弱性対応を理解するためには、リクエストパラメータとActionFormのマッピング方式を知ることが大事
    • Struts1.x系では、このマッピングにBeanUtilsクラスを使っているっぽい。RequestUtils#populateの中でBeanUtils#populateを呼び出している。TERAでのstruts脆弱性対応は、RequestUtils#populateに対して実施される(ことが多い?)。
  • Qiitaの記事

    • http://qiita.com/kawasima/items/670d2591bc8fea19dc1d
    • 一部引用

      RequestUtils.javaでBeanUtils.populate(bean, properties)で値を検証すること無く、populateを呼んでることに起因します。
      populateはBeanUtilsBeanのsetPropertyを順次呼び出していくわけですが、ここに問題があります。
      BeanUtilsの仕様にNestedPropertyというのがあって、要はA.B.Cとプロパティをドットつなぎで書いておくと、bean.getA().getB()と順次呼び出され、最後にsetC()で値がセットされます。ここがノーチェックなので、class.classLoader.などと書いておくと、getclass().getClassLoader()と等価であり、クラスローダにもアクセスできてしまうことになるわけです。

  • EvidenceLogFilterでリクエストパラメータのログ出力をするとき、マルチパートデータで送るとログに記録されないのは、仕様?

    • http://www.mitchy-world.jp/java/webapp/multipart.htm
    • (一部引用)

      しかし、こうするとサーバ側での処理がなかなか厄介なことになります。

      具体的には以下のような問題が起こります。
      ・通常の Request.Parameter ではパラメータを読めない
      ・アップロードされたデータはストリーム(Stream)で読み込むことになるが、一度読み込むと中身が空っぽになる
      →これが原因で サーブレット・フィルタ(Servlet Filter)でパラメータを取得してしまうとアクション・クラス(Action)ではパラメータが空になってしまう
      ・アクション・クラスで別のアクションにフォワードしてしまうとパラメータが空になってしまう

    • http://www.ecoop.net/memo/archives/2005-06-18-1.html

    • (一部引用)

      form タグで ENCTYPE=”multipart/form-data” にすると ServletRequest.getParameter(Sting) 系ではパラメータを解釈できず全く値が渡って来なくなるため、Jakarta Commons FileUpload の org.apache.commons.fileupload.DiskFileUpload.parseRequest(…) 等を使うとよい。

  • ActionFormにあるMap型のプロパティ(ここではxxxmapとする)にリクエストパラメータ「xxxmap(key)」形式でパラメータを設定すると、Mapから値を取り出すとき「getXxxmap().get("key")」の戻り値は配列となる(Stringで取り出す場合はString[]でキャストする)

  • get(set)MultipartRequestHandler()はActionFormに実装されているので、ValidatorActionFormExでもDynaValidatorActionFormExでも除去される(ポピュレートされない)。

    • これ(以下)、間違いでは???DynaValidatorFormにも実装されてるはず。

      get(set)ValidatorResults()はValidatorFormに実装されているため、(ValidatorFormを継承していない)DynaValidatorActionFormExを使ったときは除去されない(ポピュレートされる)。
      ⇒struts1.2.9-sp3のRequestUtils#populateでリクエストパラメータの「ValidatorResults.」を除去するロジックは、引数のbeanがValidatorFormのときのみ処理を行う。そもそもDyna~を使うときは除去の必要がないため。

  • CVE-2016-1182がDyna**Formに影響しない理由

    • 【仮説】 ・ValidatorFormの実装に依存? ・Dyna**Formの場合、リクエストパラメータでValidatorResultsを改ざんできない? ⇒なぜ?

Servletについて

  • filterの実行順序は、filter-mappingの並び順
  • マルチパートでActionチェインをしたときの問題点
    • http://www.mitchy-world.jp/java/webapp/multipart.htm
    • 通常の Request.Parameter ではパラメータを読めない
    • アップロードされたデータはストリーム(Stream)で読み込むことになるが、一度読み込むと中身が空っぽになる。これが原因で サーブレット・フィルタ(Servlet Filter)でパラメータを取得してしまうとアクション・クラス(Action)ではパラメータが空になってしまう
    • アクション・クラスで別のアクションにフォワードしてしまうとパラメータが空になってしまう
  • フォワードとリダイレクトの違い
    • フォワードはサーバ内部の挙動で遷移する
    • リダイレクトはいったんクライアントに戻り、遷移先を指示する
    • なのでフォワードはクライアントからは見えない、リダイレクトはクライアント自身が行う
    • なのでリダイレクトだとクラサバ間通信が2回発生する
    • 1回目の通信で投げられたリクエストは破棄される