JavaBeansに対するリフレクションとClassLoader脆弱性

今回の問題は、(SA)Strutsだけの問題ではなく、いろんなフレームワークでもちゃんと調べた方が良い話しなので、もう少し詳しく書いておきます。


Javaで、JavaBeansのプロパティにアクセスする場合、


PropertyDescriptor[] descriptors = Introspector.getBeanInfo(クラス).getPropertyDescriptors();
で取得できるPropertyDescriptorを使うことがほとんどです。この中に、classプロパティは含まれます。
ここまでは良くて、ネストしたリクエストパラメータ(class.classLoader.xxxなど)をJavaBeansにセットする時に、BeanInfo.getPropertyDescriptors()で取得したものをそのまま使うのが問題なのです。


Seasar2(BeanDesc)では、classプロパティとObjectのプロパティは除外してます。
Seasar2に対応したフレームワークで、HOT deployをサポートしているフレームワークは、まちがいなくBeanDescを使っています。標準のjava.beans.Introspectorを使うとHOT deployがうまく行かないからです。
なので、TeedaS2JSFなども大丈夫。S2Strutsは追記の方に書いてあります。


commons BeanUtilsを使っている場合は、今回の問題が発生するので、BeanUtilsにパッチを当てて、classプロパティとObjectのプロパティを対象外にするのが、根本的な対応だと思います(自分ならそうします)。
パラメータ名を正規表現ではじくだとかは、Objectのプロパティが将来的に増えた時に、ちょっと心配。


commons BeanUtils以外では、SpringにもBeanUtilsというクラスがあったと思うので、Springな人は、チェックしましょう。


追記:BeanUtilsレベルでは、Objectのプロパティにアクセスできても良いんじゃないかという意見ももっともですが、"aaa.bbb.ccc"のようなある種の式言語でObjectのプロパティにアクセスできると今回のようなセキュリティーホールが発生するリスクがあるので、BeanUtilsレベルで止めていた方が安全じゃないかなと思います。セキュリティーの話しなので、固い方に振っておいた方が良いという意味。
追記2:S2Strutsは、1.2はアウト。1.3はまだ、調べ中です。
追記3:S2Struts 1.3はPOJO ActionはOK、POJO ActionFormはNGです。
追記4:さらに懸賞の結果、S2Strutsは1.2も1.3もPOJO ActionはOK、POJO ActionFormはNGでした。