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を改ざんできない? ⇒なぜ?