TERASOLUNA 5.x学習(4.2 例外ハンドリング)
ガイドライン
学習のポイント
- 細部にとらわれないこと
- 分析や解釈の罠にはまらないこと
- ストーリーを作ること
- どんな利用状況がある?
- 誰向けの説明?誰向けのシステム?
- 口頭で説明できる?
- 構造の理由を腹落ちさせること
- セキュリティ
- 開発生産性
- 動作イメージを腹落ちさせること
- メタファを作ること
- トライアンドエラーできる環境を作ること
- 情報を整理しようとするな(しすぎるな)
- けっこう自分の悪いクセではある
- 情報はどんどんフローで流す
- かけ流しながら都度考える
- かけ流しなら書き流すとよい
- 最後の最後で整理すればよい
課題
- 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 入力チェック)
ガイドライン
学習のポイント
- 細部にとらわれないこと
- 分析や解釈の罠にはまらないこと
- ストーリーを作ること
- どんな利用状況がある?
- 誰向けの説明?誰向けのシステム?
- 口頭で説明できる?
- 構造の理由を腹落ちさせること
- セキュリティ
- 開発生産性
- 動作イメージを腹落ちさせること
- メタファを作ること
- トライアンドエラーできる環境を作ること
- 情報を整理しようとするな(しすぎるな)
- けっこう自分の悪いクセではある
- 情報はどんどんフローで流す
- かけ流しながら都度考える
- かけ流しなら書き流すとよい
- 最後の最後で整理すればよい
課題
書き流し
- Bean Validation
- Hibernate Validator
- Expression Language(依存ライブラリ)
- tomcat-embed-el
- pom.xml
- クライアントサイドの入力チェック
- サンプル実装をさくっと作れるか
- FormクラスにBean Validation用アノテーション
- Controllerクラスに、@Validatedアノテーション
- Springのアノテーションの検証できるか
- spring-mvc.xmlの<mvc:annotatio-driven>
- シリアルバージョンID=1L
- Spring MVCが扱う@NotNullアノテーション
- 複雑すぎないか?
- Spring入門から読まないと意味不明
- アノテーションのメタファがほしい
- アノテーションの動作原理(Springの動作原理)
- たかだか(?)入力チェックのためにここまで覚えなければいけないことが多いの?
- トライアンドエラーどうやればいいの?
- Hibernate Validatorが用意するアノテーション
- ValidationMessages.propertiesValidationMessages.properties
- @NotNul,@Null,@Pattern,@Min,@Max,@DecimalMin,@DecimalMax,@Size,@Digits,@AssertTrue,@AssertFalse,@Future,@Past,@Valid
- terasoluna-gfw-commonが用意するアノテーション
- @ExistInCodeList
- terasoluna-gfw-codepointsが用意するアノテーション
- @ConsistOf
- terasoluna-gfw-validatorが用意するアノテーション
- @ByteMin,@ByteMax,@Compare
Webについて
- applictaion/x-www-form-urlencoded
- http://wagavulin.hatenablog.com/entry/2015/10/18/060938
- POSTでボディをURLエンコードで送信するときのContent-Type。
- formタグで送るときは(enctypeで)特に指定する必要はない。
- curlコマンドでは--data-urlencode使ったりするらしい。
- formタグでマルチパート送信するときはenctype="multipart/form-data"をつける。
- GETとPOSTの違い
- http://www.fujitsu.com/jp/solutions/infrastructure/dynamic-infrastructure/sdas/technology/web-apl/01-http-protocol/
GET
データの種類: テキストのみ
データサイズ: 最大255文字
可視性: ブラウザのURLフィールドに表示されてしまう
上りデータ: ブラウザのURL履歴に残るPOST
データの種類: テキストおよびバイナリ
データサイズ: 制限なし
可視性: 表示されない
Tomcatについて
Tomcat Webアプリケーションマネージャ(Web画面でデプロイが可能になる)を有効にするには、conf/tomcat-users.xmlに以下を追記する。
- localhost:8080で画面右上にある「Manager App」ボタンを押すと該当画面に飛ぶ。ユーザパスワードはconf/tomcat-users.xmlに設定したものを使う。
- 参考:
- http://www.atmarkit.co.jp/ait/articles/0711/20/news125.html
<role rolename="manager-gui"/>
<role rolename="admin"/>
<user username="tomcat" password="tomcat" roles="manager-gui,admin"/>
- http://www.atmarkit.co.jp/ait/articles/0711/20/news125.html
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
Strutsの脆弱性について
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)ではパラメータが空になってしまう
・アクション・クラスで別のアクションにフォワードしてしまうとパラメータが空になってしまう- (一部引用)
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[]でキャストする)
- 現時点では理由が理解できていない。こうしないとClassCastException([Ljava.lang.String; cannot be cast to java.lang.String map…)がでる。
- http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=20112&forum=12
get(set)MultipartRequestHandler()はActionFormに実装されているので、ValidatorActionFormExでもDynaValidatorActionFormExでも除去される(ポピュレートされない)。
- これ(以下)、間違いでは???DynaValidatorFormにも実装されてるはず。
get(set)ValidatorResults()はValidatorFormに実装されているため、(ValidatorFormを継承していない)DynaValidatorActionFormExを使ったときは除去されない(ポピュレートされる)。
⇒struts1.2.9-sp3のRequestUtils#populateでリクエストパラメータの「ValidatorResults.」を除去するロジックは、引数のbeanがValidatorFormのときのみ処理を行う。そもそもDyna~を使うときは除去の必要がないため。
- これ(以下)、間違いでは???DynaValidatorFormにも実装されてるはず。
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回目の通信で投げられたリクエストは破棄される